In my previous in this series I already announced that we will create a Service and Client now to work with. This service and client will share a contract and schema, so our first action will be defining this.

In these posts, I’ll work on a simplified case. I’ve chosen to implement some sort of Vehicle Registration System (VRS).  Here in The Netherlands, we have a couple of so called ‘Traject Controles’. Their sole purpose is identifying passing vehicles and registering their speed. If the average speed is above the allowed limit, a speeding ticket is created automatically and the driver can expect this ticket in the mailbox within some weeks.
So, why not create a simplified version of this system.

So, let's fire up VS2008 and start creating some services :)  For now, we focus on three services:image

- Person Service, to maintain persons (drivers, license owners);

- Speed Measurement Service, to maintain the speed measurements themselves and the measurement points on the road;

- Vehicle Service, to maintain the vehicles on the road.

I’ll show you the SpeedMeasurementService in this post.

Create a new Class Library called ContractLibrary. We'll put our services in here, so they can easily be reused.

So what does a service interface look like? Check this:

   1: [ServiceContract]
   2:     public interface ISpeedMeasurementService
   3:     {
   4:         [OperationContract(IsOneWay=true)]
   5:         void AddSpeedMeasurement(SpeedMeasurement request);
   6:     }

Its just a normal interface! But we decorate it with some WCF attributes. First, the interface is decorated with the ServiceContract attribute. This indicates that the interface defines a service contract in a Windows Communication Foundation (WCF) application.
The methods on the interface resemble the service operations. These methods are decorated with the OperationContract attribute. This indicates that this method defines an operation that is part of a service contract in a Windows Communication Foundation (WCF) application.


The IsOneWay parameter on the OperationContract attribute, tells WCF that this operation is a One way shape (a shape is also known as a Message Exchange Pattern). I use this shape here, because I don’t have a return value, and I don’t care about the success of the operation call. It’s a sort of fire and forget.  Read this for more information about one way operations.

So, now we want to implement this service contract. We add a Web Application project to our solution and add a new class to it called ‘SpeedMeasurementService.svc.cs’:

   1: public class SpeedMeasurementService : ISpeedMeasurementService
   2:     {
   3:  
   4:         #region ISpeedMeasurementService Members
   5:  
   6:         public void AddSpeedMeasurement(ContractLibrary.SpeedMeasurement request)
   7:         {
   8:         }
   9:  
  10:         #endregion
  11:     }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

To be able to host this service within our web application, this application needs an entry point to reach the service. That is why on the web server, the .svc extension is registered and mapped to the ASP.NET process.
As you can see, the content of this svc file just points to the implementation of the service:

   1: <%@ ServiceHost Language="C#" Debug="true" Service="VRS_Web.SpeedMeasurementService" CodeBehind="SpeedMeasurementService.svc.cs" %>
   2:  



Now this is in place, we only need some configuration for this service. In the web.config of the web application, we have the following configuration section:

   1: <system.serviceModel>
   2:         <behaviors>
   3:             <serviceBehaviors>
   4:                 <behavior name="VRS_Web.SpeedMeasurementServiceBehavior">
   5:                     <serviceMetadata httpGetEnabled="true"/>
   6:                     <serviceDebug includeExceptionDetailInFaults="false"/>
   7:                 </behavior>
   8:             </serviceBehaviors>
   9:         </behaviors>
  10:         <services>
  11:             <service 
  12:         behaviorConfiguration="VRS_Web.SpeedMeasurementServiceBehavior" 
  13:         name="VRS_Web.SpeedMeasurementService">
  14:                 <endpoint 
  15:           address="" 
  16:           binding="wsHttpBinding" 
  17:           contract="ContractLibrary.ISpeedMeasurementService">
  18:                 </endpoint>
  19:                 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
  20:             </service>
  21:         </services>
  22:     </system.serviceModel>

The WCF configuration is always contained within the system.serviceModel section. First, in lines 3-8 we define a behavior for our service. This behavior enables metadata exposure (this means that the WSDL can be requested), and it disables the leaking of exception details from our service.

From line 11-24 we define the service. At line 12 we couple the defined behavior to our service. At line 14 we define the first endpoint for this service. You can see the Address, Binding and Contract. The address is empty so WCF will use the web application URL. We choose to use the WSHttpBinding here; more info on bindings in a later post. The contract is our service contract. At line 19 we define the second endpoint. This is the endpoint where the WSDL will be exposed.

If we now start the web application and browse to the svc file, we will see this:
image

If we click on the link, we will see the WSDL of this service:

image

 

 

 

So now our service is up and running, how are we going to call it?
In this post, I’ll create a Console app in which I will call the speed measurement service. First I add a console application to the solution.
Then, I choose the ‘Add Service Reference’ option and fill in the URL of the service as seen on the above screenshot.
Visual Studio will generate a client proxy for me (internally the svcutil.exe tool is used), which we will use to call the service.
Within the console application I add the following implementation:

   1: static void Main(string[] args)
   2:         {
   3:             SpeedMeasurementServiceClient client = new SpeedMeasurementServiceClient();
   4:  
   5:             SpeedMeasurement m1 = new SpeedMeasurement()
   6:             {
   7:                 License = "1234",
   8:                 Speed = 120,
   9:                 DateTime = DateTime.Now,
  10:                 Point = new SpeedMeasurementPoint()
  11:                 {
  12:                     Id = 1
  13:                 }
  14:             };
  15:  
  16:             SpeedMeasurement m2 = new SpeedMeasurement()
  17:             {
  18:                 License = "1234",
  19:                 Speed = 120,
  20:                 DateTime = DateTime.Now.AddSeconds(60),
  21:                 Point = new SpeedMeasurementPoint()
  22:                 {
  23:                     Id = 2
  24:                 }
  25:             };
  26:             
  27:             
  28:             client.AddSpeedMeasurement(m1);
  29:             client.AddSpeedMeasurement(m2);
  30:             client.Close();
  31:         }

 

 

 

 

 

 

At line 3 we create a new instance of the generated client proxy. In lines 5-14 and 16-25 I create two speed measurements using object initializers.
The SpeedMeasurementPoint objects are there to identify the point where the speed is measured.
In lines 28 and 29 we call our service with the measurements as parameters. If you set a breakpoint in the AddSpeedMeasurement service operation you will see the service operation getting called.

So there it is! A service, configured and running, and a client calling it´s service operation!
I will continue showing ins and outs of WCF using this application in the next posts.


Posted in: .NET 3.0 , .NET 3.5 , WCF  Tags:

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Page List

    Calendar

    «  July 2010  »
    MoTuWeThFrSaSu
    2829301234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678
    View posts in large calendar

    Recent Comments

    Feedburner Statistics 7/29/2010
    0 Readers ~ 0 hits ~ 0 reach

    Disclaimer
    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2010 Inwit.nl