Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / database / SQL-Server

GPS Tracer Extension: Storing the Path on SQL2005 via Web Services

4.72/5 (7 votes)
21 Aug 20075 min read 1   282  
This article extends Leonardo Salvatore's project using the Web Service Software Factory
Screenshot - Article.gif

Introduction

In this article we want to add a simple extension to the project seen in the CodeProject article, A GPS Tracer Application for Windows Mobile CE 5. We want to create a Web Service which can be invoked by the mobile application to store, on a remote SQL2005 database, the path followed by different GPS devices. The easiest and fastest way to achieve this result is represented by the Web Service Software Factory (next WSSF for short). This strategy is, at the same time, the best way to build higher quality service using well known patterns and practices.

Background

A GPS tracer application for Windows Mobile CE 5; Web Services Software Factory

Using the Code

Our goal is incredibly simple: we just want to store an ordered collection of GPS coordinates (a path) sent by a mobile device. Obviously we desire to distinguish between different devices, and respective paths, which can send information contemporarily.

First of all I created two tables in a database named GpsTracer: the tables are Device and LocationEntry and are defined by the following SQL statements:

SQL
CREATE TABLE [dbo].[Device](
    [ID] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Device_ID]  _
        DEFAULT (newid()),
    [CreationDate] [datetime] NOT NULL,
    [LastLoginDate] [datetime] NOT NULL,
 CONSTRAINT [PK_Device] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO

CREATE TABLE [dbo].[LocationEntry](
    [ID] [uniqueidentifier] NOT NULL CONSTRAINT [DF_LocationEntry_ID]  _
        DEFAULT (newid()),
    [IDDevice] [uniqueidentifier] NOT NULL,
    [Latitude] [float] NULL,
    [Longitude] [float] NULL,
    [WhenInserted] [datetime] NULL,
    [Speed] [float] NULL,
    [Quote] [float] NULL,
    [Heading] [float] NULL,
 CONSTRAINT [PK_LocationEntry] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]GO
ALTER TABLE [dbo].[LocationEntry]  WITH CHECK ADD  _
    CONSTRAINT [FK_LocationEntry_Device] FOREIGN KEY([IDDevice])

This structure is quite simple but it's powerful enough for our purpose: we just want to collect the devices connected (identified by their Guid) and their first and last connection to the system (device table); we want to know the paths they have ever followed (LocationEntry table). Please note that structure and tables of the database are the foundation of the solution built with the WSSF (and not only with that!;)) so we suggest thinking them carefully before starting with the code generation: of course, due to the nature of this "demo-project", we can go on.

After the DB definition, the biggest part of the rough work is done by the WSSF. Once we created, in Visual Studio, a new project of type "Web Service Software Factory (ASMX)", we should follow these steps (please refer to the Visual Studio Guidance Navigator window and it's "recipes" for more details; please remember to rebuild solution between the steps):

  • Connect the infrastructure to the DB in the Service project: a connection string is added to the web.config file
  • Create The CRUD Stored Procedure for the DB tables in the Data Access Project: an SQL statement file is generated (see GpsTracerStoredCreation.sql)
  • Create the Business Entities based on the DB tables in the Business Entity project: the classes Device and LocationEntry are created
  • Create the Data Repository Classes from Business Entities in the Data Access Project: the classes for connecting the entities and the DB are created.
  • Create a Data Type accepted by the Web Service: the objects of this type will be the ones sent by the mobile application to the web server and they will contain all the information needed for the insertion of a "footstep" (a single step in the GPS path) in the DB. In our case the type DeviceAndLocation contains the fields of both the DB tables: deviceID, deviceCreationDate, deviceLastLoginDate, locationEntryLatitude, locationEntryLongitude and so on.
  • Create a Service Contract in the corresponding project: this is the signature of the Web Method that will be created. In our example it is named SendDeviceAndLocation, it returns a Boolean and has one input parameter of type DeviceAndLocation.
  • Create the Service Contract Translators from the data type to the Business Entities. In our example this direction is enough because our application just receives data from the mobile devices. We define two translators: one from the data type to the device BE and one from the data type to the location BE.
  • Add business logic to our solution: in our simple solution we add the class DeviceAndLocationBLL with the single method AcquireDeviceAndLocation (see code described below).
  • Generate the Service Implementation: here we can finally implement our service (see code described below).
  • Expose the service: the ASMX file is generated.
  • Add web reference and implement a test, in the windows form test project, to check if insertion goes well!

Points of Interest

The few lines of code that we have to write are related to the method in the business logic and the service method. Let's start with the BLL.

This method checks if the device that sends information is already in the Device table: if it's present then we update its last login date, else we insert it into the table.

Its peculiarity consists in the use of the GetAllFromDevice (automatically created as Data Repository Classes from the CRUD stored procedures) whose result is filtered with the find method of a "generics list". The Predicate of the find method is an anonymous delegate that checks if the ID of the input device parameter "fits" to an element of the list. Please note that the method is STATIC: a class method is preferable for the performances and we don't need to mind the atomicity of operations due to the use of the DB.

C#
public class DeviceLocationBll
{
    public static bool AcquireDevice(Device inDev, LocationEntry inLoc)
    {
        DeviceRepository devRep = new DeviceRepository("GpsTracer"); 
        //"GpsTracer" is the name of the connection string in web.config

        List<device /> listDev = devRep.GetAllFromDevice();

        Device devResult = listDev.Find(
            new Predicate<device />(
                delegate(Device devv)
                {
                    return devv.ID == inDev.ID;
                }
            )
        );
        if (devResult == null)
        {
            devRep.Add(inDev);
        }
        Else
        {
        devResult.LastLoginDate = DateTime.Now();
        }

        LocationEntryRepository locRep = 
            new LocationEntryRepository("GpsTracer");
        locRep.Add(inLoc);
            
        return true;
    }
}

The service implementation is quite easy: we just need to translate the object received from the web and pass the results to the AcquireDevice method.

C#
public bool SendDeviceAndLocationInfos
    (GpsTracerServer.DataTypes.DevicePlusLocationType 
        SendDeviceAndLocationInfosRequest)
        {
            BusinessEntities.Device dev =
    TranslateBetweenDevicePlusLocationTypeAndDevice.
     TranslateDevicePlusLocationTypeToDevice
        (SendDeviceAndLocationInfosRequest);
            BusinessEntities.LocationEntry loc = 
    TranslateBetweenDevicePlusLocationTypeAndLocationEntry.
     TranslateDevicePlusLocationTypeToLocationEntry
        (SendDeviceAndLocationInfosRequest);
            return DeviceLocationBll.AcquireDevice(dev,loc);
        }

A very simple test implementation in the windows form is the following: we instantiate the proxy class which is needed to translate our DeviceAndLocation to the corresponding soap packet.

C#
private void ExecuteButton_Click(object sender, EventArgs e)
{
    //TODO: Call proxy method
    GpsTracerServiceContract ws = new GpsTracerServiceContract();

    DeviceAndLocation testDev = new DeviceAndLocation ();
    testDev.DeviceID = new Guid().ToString();
    testDev.DeviceCreationDate = DateTime.Now;
    testDev.DeviceLastLoginDate = DateTime.Now;
    testDev.LocationHeading = 10;
    testDev.LocationLatitude = 11;
    testDev.LocationLongitude = 12;
    testDev.LocationQuote = 13;
    testDev.LocationSpeed = 14;
    testDev.LocationWhenInserted = DateTime.Now;

    ws.SendDeviceAndLocationInfos(testDev);
}

In this article, we put the hands on the Web Service Software Factory and the result is a simple web service based on a robust, extensible, well engineered foundation. We just emphasize that the entire solution can be built in 15 minutes and with a few lines of code.

History

Nothing to add... at this moment!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here