Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Building a Generic Data Feed Web Service

0.00/5 (No votes)
31 Dec 2010CPOL2 min read 22.3K   176  
How to build a multi-purpose Web Service for recieving multiple data feeds.

Introduction

Electronic data transfer is an efficient and desirable solution for sharing data among agencies. The purpose of this article is to illustrate an alternative generic method using a Web Service that has the ability to receive any number of data feeds. The data file is processed by a custom program that monitors the delivery folder.

Background

The agency I work for is developing electronic data feeds in order to share case data more efficiently with other criminal justice agencies. By sending the data electronically, we save data entry time and transcription errors. We wanted a solution that would allow any agency to start sending data without the need of a new Web Service for each one.

Overview

The solution uses the Command and Factory Design Patterns to create an easily adaptable service. The Command object encapsulates the work to process the data feed - a different Command object is created for each feed. The Factory method is used by the service to instantiate the required Command object by name. The service takes two String parameters: the name of the data feed and the data itself.

This article assumes that you know how to set up an ASP.NET Web Service solution in Visual Studio.

Using the Code

For this article, I will show and discuss only the code for a "catch-all" Command object and how to use it in the service.

The "CaseElse" Command Class

The purpose of this class is to handle an unrecognized data feed; i.e.: one that does not have a Command object with the same name. The Execute() method does the following:

  1. Ensures that the base directory exists.
  2. Ensures that a directory with the same name of the data feed exists within the base directory.
  3. Saves the data in the appropriate directory, using the current date/time, down to the millisecond, as the file name.

This class inherits ACommand, an abstract class that contains everything I need except the implementation of the Execute() method. You can view that in the download. The code for the CaseElse class is shown below:

VB
Imports System.IO
Imports System.Data
Imports Microsoft.VisualBasic

Public Class CaseElse
    Inherits ACommand

    Public Overrides Function Execute( _
        ByVal args As PropertyCollection _
    ) As Object

        Dim feedName As String = args("feedName")
        Dim xmlData As String = args("xmlData")
        Dim fileName As String = Format(Date.Now, _
            "yyyyMMddhhmmssfff") & ".xml"
        Dim wrt As StreamWriter

        Try

            If Not Directory.Exists(mBaseDirectory) Then
                Directory.CreateDirectory(mBaseDirectory)
            End If

            If Not Directory.Exists(mBaseDirectory & feedName & "\") Then
                Directory.CreateDirectory(mBaseDirectory & feedName & "\")
            End If

            wrt = New StreamWriter(mBaseDirectory & feedName & "\" & fileName)
            wrt.Write(xmlData)
            wrt.Flush()
            wrt.Close()

            Return "Okay"

        Catch ex As Exception

            Return ex.ToString

        Finally

            wrt = Nothing

        End Try

    End Function

End Class

The Send() Method of the "Service" Class

The Send() methods accepts two String parameters: the name of the data feed and the data itself. It uses the CreateInstance() method of the System.Activator class in an attempt to instantiate an instance of a Command object with the same date feed name. If that fails, then a CaseElse Command object is instantiated. The Command object is then initialized and the result of its Execute() method is sent back to the consumer of the Web Service.

The code for the Service() method is shown below:

VB
<webmethod()> _
Public Function Send( _
    ByVal feedName As String, _
    ByVal xmlData As String _
) As String
    Dim cmd As ACommand
    Dim args As PropertyCollection
    Dim pHandle As System.Runtime.Remoting.ObjectHandle

    Try

        args = New PropertyCollection
        args.Add("xmlData", xmlData)

        Try

            pHandle = System.Activator.CreateInstance("App_Code", "App_Code." & feedName)
            cmd = CType(pHandle.Unwrap, ACommand)

        Catch ex As Exception

            cmd = New CaseElse
            args.Add("feedName", feedName)

        End Try

        cmd.Initialize(feedName)
        Return DirectCast(cmd.Execute(args), String)

    Catch ex As Exception

        Return ex.ToString

    Finally

        pHandle = Nothing
        cmd = Nothing

    End Try

End Function

Summary

This article outlines the critical concepts for building a generic data feed Web Service. The full source code for the Web Service is in the download file. It was written in Visual Studio 2008.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)