RESTFUL WCF Service


Download code sample

WCF has very good support for Representational State Transfer (REST) which is very popular since its introduction in 2000 by Ray Thomas Fielding in his PhD dissertation. REST builds on the client-server architecture where clients can make requests of services. There are lots of reasons to use REST. I am not going to describe them. Instead, in this article I will show you how to develop RESTFUL WCF service, host it in ASP.NET application (apparently IIS) and consume it.

Let’s Begin

For every WCF application, we need to have service contract that is an interface exposing. Make sure your project has reference to System.ServiceModel and System.ServiceModel.Web namespace.


[ServiceContract]
public interface IMService
{
 [OperationContract]
 [WebGet(UriTemplate = "Books", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
 List GetBooks();

[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "Book/{id}", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
BookModel GetBook(string id);

 [OperationContract]
 [WebInvoke(Method = "PUT", UriTemplate = "AddBook/{bookName}", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
 string AddBook(string bookName);

 [OperationContract]
 [WebInvoke(Method = "POST", UriTemplate = "UpdateBook/{id}/{bookName}", BodyStyle =  WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
 bool UpdateBook(string id, string bookName);

 [OperationContract]
 [WebInvoke(Method = "DELETE", UriTemplate = "DeleteBook/{id}", BodyStyle = WebMessageBodyStyle.WrappedRequest,  ResponseFormat = WebMessageFormat.Json)]
 bool DeleteBook(string id);
}

In above code, subtle difference is WebGetAttribute and WebInvokeAttribute. WebGetAttribute is for GET HTTP request while WebInvokeAttribute by default invokes POST HTTP request but it can be specified in Method to support other verbs like GET, PUT and DELETE. Inside both attributes there is UriTemplate which makes it possible to define URI for each resource by using specific template syntax. It is clear curly braces is being used for parameter. You can also specify the message format of the response. Default is xml. If we define the service implementing above interface, we can call http://localhost:port/Books to get the all books in json format. Easy, huh?

Configuration

To make the service RESTful we need to specify certain things on our service configuration. Yes, it is ABC of WCF. We need to define binding as “webHttpBinding” with webHttp behavior. Here is the service configuration, I used for this article.

<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true" />
    <services>
      <service name="InetPrep.MathService.MService" behaviorConfiguration="">
        <endpoint address="" binding="webHttpBinding" behaviorConfiguration="restfulBehavior" contract="InetPrep.MathService.IMService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/MService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="restfulBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>

For this sample, I have hosted my service in ASP.NET application. You need to add reference to the actual service implementation project if they are two different projects. All of the configuration will reside inside web.config file. To make the sample project more realistic, I am doing direct query to the database using Entity framework. Entire database script is in project if you want to import. To host the service in ASP.NET (IIS), we can add .svc file which hosts the service. There is very little code you need to worry about for this file.

<%@ ServiceHost Language="C#" Debug="true" Service="InetPrep.MathService.MService"%>

This file uses the configuration from the web.config file and hosts the service.

Service is Hosted now WHAT?

If you browse to http://localhost:40235/MathServiceHost.svc/Books, you will get json books data. Similarly, if you browse to http://localhost:40235/MathServiceHost.svc/Book/2, you will get information about a book with id 2. Useful, right? Now let’s try to add new book http://localhost:40235/MathServiceHost.svc/AddBook/newbook, you will get ‘Endpoint not found’. Similar message will be displayed, if you try to update and delete book. So, why is that? This is because whenever you type and browse url from your browser, it will be treated as GET request and there is not any matching operation we defined. To perform those operations you need to do that in different ways; 1. You can create HTML form and perform operation. 2. You can programmatically create requests and perform operation. Or 3. You can use Fiddler to create request and perform operation. I have created sample client project which allows you to add book. If you see in code-behind you can see code to create PUT request. You can easily do this using jQuery from client side.

var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:40235/MathServiceHost.svc/AddBook/" +    txtBookName.Text);
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "PUT";
string responseText = "";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
 //streamWriter.Write(txtBookName.Text);//any parameter
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
 responseText = streamReader.ReadToEnd();
 lblMessage.Text = responseText;
}

Summary

So this concludes the basic RESTful service. It utilizes the basic building block of WCF to create RESTful service and shows you to host it in ASP.NET application. Please, do not hesitate to post any questions related to this article.

Advertisements