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

Building and Testing WCF RESTful services

4.71/5 (9 votes)
12 Mar 2012CPOL4 min read 167.6K   6.1K  
Building and Testing WCF RESTful services

Introduction

Following article will cover, how to build a RESTful service using the WCF framework. What I also want to achieve is to have multiple end points.

1. RESTful end point

2. TCP IP end point.

By doing this, we can try to cater to different set of clients. RESTful services can be accessed by all kind of clients and TCP IP can be access by .Net clients. As many of you would already aware that the TCP/IP is the best suited for better performance. At the end of article, I will also cover how you can test your REST based service using a fiddler tool.

What is REST

• REST stands for Representational State Transfer

• REST is about accessing resources through a universal interface.

• REST URI: Uniform Resource Identifier - This is a unique way of identifying resources on the network.

• You can also refer following link to get to know all REST terminologies.

http://msdn.microsoft.com/en-us/library/dd203052.aspx

Steps used to Achieve the above stated Objective

Add Services

• Add a library project to a solution

• Implement services using IService interface and Service Contract.

• Service will in turn interact with Northwind database.

Host Services

• Add a console application and

• Configure the app.config with TCP/IP and RESFful service.

• Host services in the console application.

Test Services

• Create a windows application to consume services.

1. RESTful endpoint

2. TCP/IP endpoint

• Test Restful Services using Browser and Fiddler tool

Add Services

• Create a .Net solution

• Add a library project with name SampleServices.

• Add “LINQ to SQL” class, Northwind.dbml.

I want to communicate to category table of Northwind database. Once you have Added Northwind.dbml file, connect to a local server using server explorer in the LINQ designer. Then drag and drop category table on to the LINQ designer.

Figure1.jpg

• You will have to change the SQL connection string to point to your local server, which has northwind database.

• Add c# classes IService and Service

• Make sure you add following reference System.ServiceModel & System.ServiceModel.Web

• IService Interface Code

    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        [WebInvoke(UriTemplate = "/Category/{categoryID}", Method = "GET")]
        Category GetCategory(string CategoryID);
        [OperationContract]
        [WebInvoke(UriTemplate = "/Category", Method = "GET")]
        List
<category /> GetCategories();
        [OperationContract]
        [WebInvoke(UriTemplate = "/Category/Add", Method = "POST")]
        bool AddCategory(Category category);
    }

• Service Code

    public class Service : IService
    {
        public Category GetCategory(string categoryID)
        {
            NorthwindDataContext context = new NorthwindDataContext();
            var category = context.Categories.SingleOrDefault(e => e.CategoryID == Convert.ToInt32(categoryID));
            context.Dispose();
            return category;
        }
        public List
<category /> GetCategories()
        {
            NorthwindDataContext context = new NorthwindDataContext();
            var categories = context.Categories.ToList();
            context.Dispose();
            return categories;
        }
        public bool AddCategory(Category category)
        {
            NorthwindDataContext context = new NorthwindDataContext();
            context.Categories.InsertOnSubmit(category);
            context.SubmitChanges();
            context.Dispose();
            return true;
        }
    }

Host Services

• Add a console application “ServiceHost”

• Make sure you add reference to System.ServiceModel assembly.

• Add Reference to SampleService.dll

• Configure the app.config to support REST and TCP/IP endpoints

  <system.serviceModel>
  <services>
    <service name="SampleServices.Service" behaviorConfiguration="MYServiceBehavior">
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      <endpoint address="net.tcp://localhost:12000/SampleServices/Service" binding="netTcpBinding" bindingConfiguration="TCPBindingDetails" contract="SampleServices.IService" behaviorConfiguration="TCPBehavior">
      </endpoint>
      <endpoint name="webHttpBinding" address="REST" binding="webHttpBinding" behaviorConfiguration="RESTBehavior" contract="SampleServices.IService" />
      <host>
        <baseAddresses>
          <add baseAddress="<a href="http://localhost:9002/SampleServices/Service/">http://localhost:9002/SampleServices/Service/</a />" />
        </baseAddresses>
        <timeouts closeTimeout="01:20:10" openTimeout="01:20:00" />
      </host>
    </service>
  </services>
  <bindings>
    <netTcpBinding>
      <binding name="TCPBindingDetails" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="5000000" maxBufferSize="5000000" maxConnections="10" maxReceivedMessageSize="5000000">
        <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
        <reliableSession ordered="true" inactivityTimeout="00:30:00" enabled="false" />
        <security mode="Transport">
          <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
          <message clientCredentialType="None" />
        </security>
      </binding>
    </netTcpBinding>
  </bindings>
  <behaviors>
    <endpointBehaviors>
      <clear />
      <behavior name="TCPBehavior">
        <dataContractSerializer maxItemsInObjectGraph="6553600" />
      </behavior>
      <behavior name="RESTBehavior">
        <dataContractSerializer maxItemsInObjectGraph="6553600" />
        <webHttp helpEnabled="true" />
      </behavior>
    </endpointBehaviors>
    <serviceBehaviors>
      <behavior name="MYServiceBehavior">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="True" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

Note: helpEnabled="true"<webhttp helpenabled="true">, is used to enable Automatic help pages for the RESTful service

• Hosting code in program.cs

static void Main(string[] args)
{
    // Create a ServiceHost for the CaseStudyService type.
    System.ServiceModel.ServiceHost serviceHost = new
        System.ServiceModel.ServiceHost(typeof(SampleServices.Service));

    // Open the ServiceHost to create listeners and start listening for messages.
    serviceHost.Open();
    Console.WriteLine("Services are ready & running.");
    Console.WriteLine();
    Console.ReadLine();
}

Test Services

• Create a windows application, “Client”

• Add references to System.ServiceModel & System.Runtime.Serialization

• Generate proxy using svcutil.exe

• Add proxy class to the client application.

Figure2.jpg

• Sample code to access TCP IP end point.

ServiceClient client = new ServiceClient();
var allCategories = client.GetCategories();
MessageBox.Show(allCategories.Count().ToString());

• Sample Code to access REST service.

WebRequest request = WebRequest.Create("http://localhost:9002/SampleServices/Service/REST/Category/1");
WebResponse ws = request.GetResponse();
Encoding enc = System.Text.Encoding.GetEncoding(1252);
StreamReader responseStream = new StreamReader(ws.GetResponseStream());
string response = responseStream.ReadToEnd();
responseStream.Close();
MessageBox.Show(response);

• You can also test the REST based services through Browser and Fiddler tool.

• Important TIP: You can get to know following items by enabling help on the service

o URI

o Method type

o Description

o Data format expected for GET method

o Data format or Request Body for POST method.

You can get all these information by browsing to http://localhost:9002/SampleServices/Service/REST/help

Figure3.jpg

Clicking on the method will provide the sample response XML

Figure4.jpg

Clicking on the POST method will provide the Request xml to be sent.

Figure5.jpg

Get all categories in browser using RESTful service http://localhost:9002/SampleServices/Service/REST/Category

Figure6.jpg

• Get the details of the category whose ID = 1, http://localhost:9002/SampleServices/Service/REST/Category/1

Figure7.jpg

• Using Fiddler: Go to request builder in the fiddler tool and type in the url, select GET method. Then click execute button. url: http://localhost:9002/SampleServices/Service/REST/Category/

Note: Make sure that you are running the WCF host

Figure8.jpg

• You can see the response by double clicking on the request in web session panel.

Figure9.jpg

• You can see the use the fiddler for POST method also. In order add a category, we need to use URI http://localhost:9002/SampleServices/Service/REST/Category/Add , which is a POST method. We can get the request xml by using the help url.

2147483647 String content String content 1999-05-31T11:20:00 QmFzZSA2NCBTdHJlYW0=

Let us use the above format in the Fiddler tool add a new category. Remove CategoryID, as this is auto generated column in the database. Use the below format in the Fiddler tool

New Category New Category 2012-05-31T11:20:00

• Select “POST” method in the method. Provide url

http://localhost:9002/SampleServices/Service/REST/Category/Add

Add content-type: application/xml in the request header.

Add the above XML in the request body.

Figure10.jpg

• Click Execute and check in DB, if the category is inserted. You can also check it by using RESTfule service in browser. http://localhost:9002/SampleServices/Service/REST/Category

Figure11.jpg

Resources

http://benjii.me/2010/03/5-lifesaving-tips-for-creating-a-wcf-restful-api-in-net-4/

Conclusion

Article covers having multiple endpoints for the WCF service. Service was configured with TCP/IP and RESTful endpoint. This might be useful in those projects, where you would want your services to be consumed by both .Net and other varied clients. .Net application can still communicate with TCP/IP endpoint, which provides the optimal performance; where as other clients can communicate with RESTful end point. I have also tried to cover different ways to test the services. We can also use WCF REST started kit to create service. I am yet to use it, and will elaborate it once I start using it.

License

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