TUTORIAL

REST Eanbaled Service in WCF Tutorial

Posted by Dhananjay Kumar Tutorials | Web Services in C# May 12, 2009
Tags: REST, WCF
This tutiorial will explain how to create and consume a basic REST Enabled service in WCF. This is very basic tutorial but it will be very helpful in debugging common error while creating REST Services.
Reader Level:
Download Files:
 

Objective:

This article will explain step to step explanation of, how to create a REST based service and how to consume that in a client. Although, this is a very simple service taken as an example, but it will really help in creating complex REST Services.

This article will help in understanding scene behind ASTORIA also.

Step 1:

Create a new project as WCF Service application type.

WCFService1.gif

Step 2:

Rename IService.cs to IRestService.cs and Service1.cs to RestService.cs. And delete all the existing code from there.

Step 3:

Open Web.Config file and delete below highlighted code. In other words delete all default bindings and endpoints for existing service model. Delete existing <system.serviceModel>

  <system.serviceModel>
    <
services>
      <
service behaviorConfiguration="RestServicePublishing.Service1Behavior"
        name="RestServicePublishing.RestService">
        <endpoint address="" binding="wsHttpBinding" contract="RestServicePublishing.IRestService">
          <identity>
            <
dns value="localhost" />
          </identity>
        </
endpoint>
        <
endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </
services>
    <
behaviors>
      <
serviceBehaviors>
        <
behavior name="RestServicePublishing.Service1Behavior">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <
serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before
deployment to avoid disclosing exception information
-->
          <
serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </
serviceBehaviors>
    </
behaviors>
  </
system.serviceModel>

Step 4:

Right click on RestService.cs and open View markup.

WCFService2.gif

In Markup of RestService.cs , add below code there

Factory="System.ServiceModel.Activation.WebServiceHostFactory"

So after adding code the markup would look like

Markup of RestService.cs

<%@ ServiceHost Language="C#" Debug="true"
Service="RestServicePublishing.RestService"
CodeBehind="RestService.svc.cs"
Factory="System.ServiceModel.Activation.WebServiceHostFactory"%>

Step 5:

Writing Service.

Add following references to the service project.

Microsoft.Http.dll
Microsoft.Http.Extension.dll
System.ServiceModel.Web.dll 

Note : These dll can be download from Microsoft site else it could be downloaded from the attached Zip file.

Step 6:

Add a new project as of type class library and give it name UtilityClasses. Rename Class1.cs to Number.cs .

WCFService3.gif

Type the below code in Number.Cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Utilityclasses
{
    [Serializable]
    public class NumberService
    {
        public int Number1 { get; set; }
        public int Number2 { get; set; }
    }
}


Step 7:

Add Namespaces to IRestService.cs

using System.ServiceModel.Web;

Step 8:

Type the below code.

IRestService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
using Utilityclasses;

namespace RestServicePublishing
{
    // NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in Web.config.
    [ServiceContract]
    public interface IRestService
    {
        [OperationContract(Name="AddParameter")]
        [WebInvoke(UriTemplate = "/",Method="POST")]
        int  Add(NumberService n1);
        [OperationContract(Name="Add")]
        [WebGet(UriTemplate = "/")]
        int Add()

     }   
    }


Explanation of Code:

This code is used to construct URI for REST service.

[WebInvoke(UriTemplate = "/",Method="POST")]

Method parameter says what type of HTTP request; this URI is going to entertain. In this case it is Http POST.

UriTemplate parameter says, what would be URI for this particular method. In this case it is one back slash means; it is root URI of this service.

So, to invoke this method add (), the URI address would be

http://localhost:3602/RestService.svc/

Where 3602 is port number of web server, where this service is running.
Let, if the above code is modified as
[WebInvoke(UriTemplate = "/ADD/Mahesh",Method="POST")]

Then it would be invoked as

http://localhost:3602/RestService.svc/ADD/Mahesh

Step 9:

Implementing the Service

RestService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Utilityclasses;
namespace RestServicePublishing
{
    // NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
    public class RestService : IRestService
    {
        public int res = 100;

        public int Add(NumberService n1)
        {
            res = Convert.ToInt32(n1.Number1) + Convert.ToInt32(n1.Number2);
            return res;
        }
        public int Add()
        {
            return res;
        }
     }
}


Step 10:

Testing the Service in browser.

  1. Build the Service
  2. Right click on RestService.cs and select view in browser.

    WCFService4.gif

Explanation of output:

Output 100 is returned in the browser by the service. It is because, below service method. URI of below GET method is mapped to root of the URI. And this method is returning 100. (See RestService.cs)

        [OperationContract(Name="Add")]
        [WebGet(UriTemplate = "/")]
        int Add()


on modifying URI in address bar of browser as below ,

http://localhost:3602/RestService.svc/abc

output would be , because given URI is not mapped to any method in the service.

WCFService5.gif

Step 11:

Consuming at client side.

Add new console project in solution and give it name as ConsoleTestProject.

WCFService6.gif

Add reference of project UtilityClasses Add following references to the console project.

Microsoft.Http.dll
Microsoft.Http.Extension.dll
System.ServiceModel.Web.dll


Step 12:

Paste or type below code in

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using Microsoft.Http;
using Microsoft.ServiceModel.Web;
using Microsoft.ServiceModel.Web.SpecializedServices;
using System.Runtime.Serialization;
using Utilityclasses;

namespace ConsoleTestProject
{
    class Program
    {
        static string uri;
        static void Main(string[] args)
        {
          
            uri = "http://localhost:3602/RestService.svc/";
            // Calling without parameter
            Console.WriteLine(AddWithoutParameter());
            Console.Read();

            //Calling with parameter
            NumberService obj = new NumberService() { Number1 = 7, Number2 = 2 };
            Console.WriteLine(AddWithParameter(obj));
            Console.Read();    
        }

        public static string  AddWithoutParameter()
        {
            using (HttpResponseMessage response = new HttpClient().Get(uri))
              
                int res = response.Content.ReadAsDataContract<int>();
                return res.ToString();
            }
        }

         public static string  AddWithParameter(NumberService obj)
        {
            using (HttpResponseMessage  response = new HttpClient().Post(uri,HttpContentExtensions.CreateDataContract(obj)))
            {
               
                int res = response.Content.ReadAsDataContract<int>();
                return res.ToString();
             }

         }
    }
}


Explanation:

There are two static methods

AddWithoutParameter() -> To Invoke HTTP Get on Service URI. {In Green}
AddWithParameter() -> To Invoke HTTP POST on Service URI. {In Yellow}

AddWithoutParameter()

This is just creating instance of HttpResponse and calling HttpClient Get method to fetch value from the service.

AddWithParameter()

This is just creating instance of HttpResponse and calling HttpClient POST method to fetch value from the service.

Output

WCFService7.gif

Future Scope:

To consume this service in SilverLight and to use REST with Ado.NET Data Service.

Login to add your contents and source code to this article
post comment
     

How you are able to create object for NumberService class as it is declared in webservice?

Posted by Sachin Gangarde Oct 01, 2012

Edit Hi,tell me one example how to insert data in database using asp.net cloud programing....pls help me.. I know asp.net,I want to cloud programing...... Seng basic leavel of cloud programming plsGive some cloud links also....Thank you, anilpls give me the answer

Posted by anil babu Jul 03, 2012

Hi,tell me one example how to insert data in database using asp.net cloud programing....pls help me.. I know asp.net,I want to cloud programing...... Seng basic leavel of cloud programming plsGive some cloud links also....Thank you, anil

Posted by anil babu Jun 25, 2012

I have a rest webservice here is details: Web.Config: ------------- <configuration> <appSettings> <add key="NYTMobileConnectionString" value="Data Source=(local);Initial Catalog=dbNYTimes;User ID=sa;Password=password"/> <add key="IsAuthenticationEnabled" value="True"/> </appSettings> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> <system.serviceModel> <services> <service name="RestService.RestServiceImpl" behaviorConfiguration="ServiceBehaviour"> <!-- Service Endpoints --> <!-- Unless fully qualified, address is relative to base address supplied above --> <endpoint address ="" binding="webHttpBinding" contract="RestService.IRestServiceImpl" behaviorConfiguration="web"> <!-- Upon deployment, the following identity element should be removed or replaced to reflect the identity under which the deployed service runs. If removed, WCF will infer an appropriate identity automatically. --> </endpoint> </service> </services> <behaviors> <serviceBehaviors> <behavior name="ServiceBehaviour"> <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> <serviceMetadata httpGetEnabled="true"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> <endpointBehaviors> <behavior name="web"> <webHttp/> </behavior> </endpointBehaviors> </behaviors> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> </system.serviceModel> <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> </system.webServer> </configuration> IRestServiceImpl.cs: ---------------------- [ServiceContract(SessionMode = SessionMode.Allowed)] public interface IRestServiceImpl { [OperationContract] [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "/login")] //"signin/{un}/{pd}" string LoginMethod(Student st); [DataContract] public class Student { [DataMember] public string RollNumber { get; set; } [DataMember] public string Name { get; set; } } } RestServiceImpl.svc.cs: ------------------------ public class RestServiceImpl : IRestServiceImpl { public string LoginMethod(Student st) { st.Name = "I have Updated Student Name"; return st.Name; //return uObj.user_name + ":" + uObj.password; } } but when i try to access this in Poster Add-on of firefox by URL: http://localhost:10155/RestServiceImpl.svc and following parameters in parameter tab of Poster: Name "ABCDEF" RollNumber "9" and on hitting POST it shows bad request error. or sometimes if luckily it hits LoginMethod() then Student Object always remain NULL plz advise :(

Posted by Faheem Sial Feb 17, 2012

Thanks Dhananjay!! That makes sense. Offlate I have been trying to secure wcf operation(Rest Service). In the sense that that only Authenticated users should be able to access my operation if they use browser URL. Do you have any suggestions/articles to do the same. Many Thanks & Regards Sankalp

Posted by Sankalp Mehra Dec 23, 2010
COMMENT USING
PREMIUM SPONSORS
Over-C is a holistic consortium of communications and technology specialists. We build, deploy and market both business as well as consumer products and solutions.
Join a Chapter
SPONSORED BY
  • PDF reports have never been easier to create. With our included WYSIWYG Designer, you can layout your reports, set up your data source and let DynamicPDF ReportWriter do the rest.