This blog is about creating RESTful web services using Windows Communicaiton Foundation (WCF) in .NET. The intention of this blog is not to teach what is Representation State Transfer (REST) but how to create web services which support REST by making use of WCF. So lets start by having a look at what was the requirement which prompted me to create a RESTful web service and how we did it.
As with any change in software, this change, to have RESTful web service was also raised by the client. The client in our case had some Business Access Layer (BAL) and he wanted to expose some of the methods to the outside world through RESTful web service. So what we did was we created a Facade layer to expose the required methods of the BAL and called exposed this Facade layer with the help of WCF web service. Thats the simple solution to our requirement. Now lets see the code wise implementation of the solution.
As per company rules and other client agreement I may not be able to publish the same implementation but will try to take another e.g. and try to replicate the same scenario and create RESTful web services. We will see two ways of creating WCF, one is implementing the interface in class file and then exposing the class methods using a .SVC file and second approach is the default way i.e. implementing an interface to a .SVC file. Lets see the first way (this was the solution implemented to solve our problem).
For creating a WCF service first thing you need is a contract. A contract is nothing but an Interface with the methods you want to expose. So lets create our contract (interface) which will be implemented by the WCF service. Any WCF webservice (RESTful or non RESTful) needs a contract, if no contract is defined then the class should be have the ServiceContract attribute to it and this is mandatory. Below is the interface definition.
using System; namespace CarService [System.ServiceModel.OperationContract] |
From the above interface definition one can see that we are using some attributes. Lets see each of these attributes one by one. First up is the ServiceContract attribute.
ServiceContract: This attribute tells the system that the interface defines a service contract for a WCF application. If an interface which is being inherited by a WCF web service doesn’t have a ServiceContract attribute then the following error will thrown by the system.
Service 'CarService' implements multiple ServiceContract types, and no endpoints are defined in the configuration file. WebServiceHost can set up default endpoints, but only if the service implements only a single ServiceContract. Either change the service to only implement a single ServiceContract, or else define endpoints for the service explicitly in the configuration file. |
Just applying the ServiceContract attribute above the interface will solve the above error. Now lets see the various properties associated with the ServiceContract attribute
Property | Description |
ConfigurationName | The element name in the configuration file which defines the service. |
Name | Using the property you can provide a different name to the interface. |
Namespace | Can be used to provide namespace. |
ProtectionLevel | enum value specifies what type of protection should be applied to the service. The enum values are ProtectionLevel.None, ProtectionLevel.Sign and ProtectionLevel.EncryptAndSign |
SessionMode | enum specifies whether sessions are allowed or not. The enum values are SessionMode.Allowed, SessionMode.Required and SessionMode.NotAllowed. |
That’ about ServiceContract attribute. The next attribute which we have used in all the methods is the OperationContract attribute. Lets see what does OperationContract do.
OperationContract: OperationContract attribute tells the system that the method needs to be exposed as part of a service contract. A method which is not having OperationContract will not be exposed. So its imperative to have OperationContract attribute to expose a method. The properties which can be used along with OperationContract are.
Property | Description |
Action | Using the action property you can specify a url to which the incoming messages needs to be posted. Action uniquely identifies a method with a Url. |
AsyncPattern | Specifies whether the method can be called asynchronously or not. |
IsOneWay | Specifies whether the operation returns a value or not. |
IsInitiating | Specifies whether the method needs to be called when session is started. |
IsTerminating | Tells the system to execute the method when session is completed. |
Name | If you want to give some other name to the method then you can make use of the name property. |
ProtectionLevel | enum value specifies what type of protection should be applied to the service. The enum values are ProtectionLevel.None, ProtectionLevel.Sign and ProtectionLevel.EncryptAndSign |
Next attribute which you will notice is the WebGet. Here is the explanation of WebGet attribute.
WebGet: If you would have worked on ASP.NET application then you know that the forms in ASP.NET post data in two ways, one is the GET method and the other one is the POST method. WebGet attribute tells the system that the method is a pure data retrieval method to which HTTP GET method is associated. The properties associated with WebGet are listed below.
Property | Description |
BodyStyle | enum specifies how messages should be sent. Enum values are WebMessageBodyStyle.Bare, WebMessageBodyStyle.Wrapped, WebMessageBodyStyle.WrappedRequest and WebMessageBodyStyle.WrappedResponse. |
RequestFormat | enum specifies what is the request format. Enum values are WebMessageFormat.Xml and WebMessageFormat.Json. |
ResponseFormat | Same as RequestFormat. Specifies the type of the response. |
UriTemplate | The Uri to access the method/operation. |
UriTemplate here is the endpoint. Here endpoint means a unique Url to access the method in a restful webservice. This is one of the requirement of a RESTful method which says there should be unique endpoint to access the methods.
One thing to note in UriTemplate property is that whatever you specify inside a curly brace, {}, and if the same name is used in the parameter of the method then the value which comes in the querystring is passed on as the parameter for the method. In our second method in the interface we have given the UriTemplate as something like this “cars/search?carName={theCarName} ” which means the querystring value in carName will be passed as the parameter to the method, as the parameter name and value inside the curly brace are the same. If you want more parameters you can very well do this by declaring more parameters in the querystring. A hypothetical method is pasted below.
[System.ServiceModel.OperationContract] |
In the above e.g. theCarName, theColor and thePrice will be passed as parameter to the method SearchCar. The url may look something like this “http://localhost:2333/cars/carsearch?carName=ferrari&color=red&price=432544”. The values ferrari, red and 432544 will be passed as parameters to the SearchCar method. So if you want to pass parameters to a RESTful web method then you need to just follow the above approach.
Now that was about making use of HTTP GET method. The next obvious question would be how to make use of HTTP POST method. To make use of HTTP POST method one need to apply another attribute called “WebInvoke” All the properties are same as in WebGet except for an extra property called Method. Using the method property you can specify the HTTP method like POST, PUT, DELETE and HEAD. When to use each of these HTTP method is given below.
HTTP Method | Description |
GET | Whenever you want to retrieve some information you will make use of get. |
POST | When you want to submit data which will be processed by the service. |
PUT | When you want create or update a resource you will make use of PUT. |
DELETE | As the name suggest whenever you want to delete a resource you will make use of DELETE. |
Now we have our contract defined. So the first step is over. Now we need to implement the interface and that is what we are going to do next. We will be implementing the interface in a class called CarService. The code is pasted below.
namespace CarService Car ICarService.GetCar(string theCarName) |
You can see from the above code we have implemented ICarService interface into a class called CarService. The first method returns the Car collection and the second method searches the carList collection object based on the name of the car and returns the matching Car object. No rocket science here. The Car class is discussed in detail at the end of the blog. So we will move on to the next step.
We have defined the base requirement and now we have to expose the methods to the outside world using WCF service. For that you can either add a new WCF Service Applicaiton project from the file menu or you can right click on your ASP.NET or web service project and from the popup menu select Add—>New Item option. From the Add New Item dialog box select WCF Service and give a name to your service. I have named it CarService. The screenshot of Add New Item dialog is pasted below.
You can do the same from file menu as well.
When you add WCF Web service application or a SVC file the system will automatically add an interface by the name ICarService or I followed by whatever name given to the project or SVC file. Delete the interface, as we have already defined the contract. Also delete the SVC.cs file. Now open the SVC file, in my case CarService.svc. You can see a markup something like this.
<%@ ServiceHost Language="C#" Debug="true" Service="CarService.CarService" CodeBehind="Service1.svc.cs" %> |
Delete the CodeBehind attribute and add Factory attribute as shown below.
<%@ ServiceHost Language="C#" Debug="true" |
You may get an error something like the one pasted below.
Service 'CarService.CarService' has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element. |
If you come across an error like this then the possible reason could be you will be missing the Factory attribute in the ServiceHost tag. Just by adding the Factory attribute will solve the prob.
Visual studio also embeds the following tag in Web.config file.
<system.serviceModel> |
Now you are ready to go. Just hit F5 and see the output. If you see a message saying there is no endpoint defined you need not panic. Just type one of the endpoints defined in the contract (interface) you can see the output. In my case the two url which I used are as follows.
http://localhost:3891/CarService.svc/cars Ouput of the above url <GetCarsResponse xmlns="http://tempuri.org/"> http://localhost:3891/CarService.svc/cars/search?carName=Ferrari Output of the above url. <Car xmlns="http://schemas.datacontract.org/2004/07/CarService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> |
The car class which is getting serialized is shown below.
[System.Runtime.Serialization.DataContract] |
The objects used in WCF should be qualified by DataContract attribute. Some of the properties of DataContract are listed below.
Property | Description |
Name | If you want to give a different name to the class when it is serialized then you can make use of the name property. |
Namespace | To provide a namespace to the xml attribute you can make use of the “Namespace” property. When you provide namespace it has abide by w3 guidelines. As a general practice we provide urls as namespace. |
The other attribute is the DataMember. DataMember attribute tells the serializer that the property/field is part of a DataContract and it can be serilizable. Some of the properties are explained below.
Property | Description |
EmitDefaultValue | Property which tells the serializer whether to emit default value if the property is not having any value. |
IsRequired | This property can be set when you want the property/field to be present while serializing and deserializing the object. |
Name | If you want to give some other name other than name of the property/field then you can make use the Name property. |
Order | When the object is serialized in what order the property/field needs to be serialized. |
Now lets see the second way of implementing the WCF webservice. This is the most common way which everyone will be aware off. Open VS 2008 and add a new project of type WCF Service Application from File—>New—>Project menu. This will automatically add a contract (interface) and the necessary .SVC files (a .svc and a .svc.cs file inheriting from the interface). Rest we need to follow the same steps for defining various methods in the Interface as explained above.
Thanks for the complement.
ReplyDeleteIts really a helpful post for me as I am creating a web application in .Net at Imenso Sotware which provides web development in .NET ,Software development .NET and other Offshore It Services.
ReplyDeleteWonderful post!!!
ReplyDeletePretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your
ReplyDeleteblog posts.
saab service contract
Great thanks! Very helpful for me.
ReplyDeleteVery well written and explained ! Thanks.
ReplyDeleteI am extremely upbeat to you to your time to impart this superb post! Much appreciated a decent alternative to impart this website to us.
ReplyDeletekeep in touch with us...
iqra technology
Angular ECommerce
Website Design and Development
Salesforce CRM Services
Microsoft Dynamics CRM Services
SEO Services
Power BI
Appreciate you bloggiing this
ReplyDelete