Click here to Skip to main content
Click here to Skip to main content

Create and Consume RESTFul Service in .NET Framework 4.0

By , 23 Mar 2012
 

About This

I am writing this article to explain creating & consuming RESTFul service using .NET Framework 4.0.

What is Web Services, WCF?

Web Service

Web Service is like components on a Web Server, client application uses this service by calling Hypertext Transfer Protocol (HTTP) requests across the Web. Using ASP.NET, we can create custom Web Services, and call these services from any client applications.

Web Services are platform, programming language independent; they send as well as receive data using Simple Object Access Protocol (SOAP) messages.

WCF

Windows Communication Foundation (WCF) is Microsoft’s combined programming model for building service-oriented architecture (SOA). Using this, the developer can build a secure, reliable, transacted solutions across platforms.

WCF supports concentrated computing where services have isolated consumers. Clients can consume multiple services as well as services can be consumed by multiple clients.

For creating basic application in WCF, please refer to the article “Introduction of Window Communication Foundation”.

Web Services WCF Services
Web services were developed for building applications that send and receive messages by using the Simple Object Access Protocol (SOAP) over HTTP. The structure of the messages can be defined using an XML Schema, and a tool is provided to facilitate serializing the messages to and from .NET Framework objects. The technology can automatically generate metadata to describe Web services in the Web Services Description Language (WSDL) WCF services were developed for building applications to send and receive messing by using many formats and conveyed by using any transport protocol. Simple Object Access Protocol (SOAP) is used by default format.The structure of the messages can be defined using an XML Schema, and there are various options for serializing the messages to and from .NET Framework objects. WCF can automatically generate metadata to describe applications built using the technology in WSDL, and it also provides a tool for generating clients for those applications from the WSDL.

Support for sending messages using not only HTTP, but also TCP and other network protocols. The ability to switch message protocols with minimal effort. Support for hosting services on hosts other than a Web server. Built-in support for the latest Web services standards (SOAP 1.2 and WS-*) and the ability to easily support new ones. Support for security, transactions and reliability. Support for sending messages using formats other than SOAP.
XmlSerializer DataContractSerializer
ASP.NET relies on the XmlSerializer to translate data represented by .NET Framework types to XML for transmission to or from a service and to translate data received as XML into .NET Framework objects. Defining the complex data types that an ASP.NET service is to use requires the definition of .NET Framework classes that the XmlSerializer can serialize to and from XML. The DataContractAttribute signifies that zero or more of a type’s fields or properties are to be serialized, while the DataMemberAttribute indicates that a particular field or property is to be serialized. The DataContractAttribute can be applied to a class or structure. The DataMemberAttribute can be applied to a field or a property, and the fields and properties to which the attribute is applied can be either public or private. Instances of types that have the DataContractAttribute applied to them are referred to as data contracts in WCF. They are serialized into XML using DataContractSerializer.
The XmlSerializer and the attributes of the System.Xml.Serialization namespace are designed to allow you to map .NET Framework types to any valid type defined in XML Schema, and so they provide for very precise control over how a type is represented in XML. The DataContractSerializer, DataContractAttribute and DataMemberAttribute provide very little control over how a type is represented in XML. You can only specify the namespaces and names used to represent the type and its fields or properties in the XML, and the sequence in which the fields and properties appear in the XML. Everything else about the structure of the XML used to represent the .NET type is determined by the DataContractSerializer. By not permitting much control over how a type is to be represented in XML, the serialization process becomes highly predictable for the DataContractSerializer, and, thereby, easier to optimize.
Lesser performance compared with WCF DataContractSerializer. A practical benefit of the design of the DataContractSerializer is better performance, approximately ten percent better performance.
The attributes for use with the XmlSerializer do not indicate which fields or properties of the type are serialized into XML. DataMemberAttribute for use with the DataContractSerializer shows explicitly which fields or properties are serialized. Therefore, data contracts are explicit contracts about the structure of the data that an application is to send and receive.
The XmlSerializer can only translate the public members of a .NET object into XML. The DataContractSerializer can translate the members of objects into XML regardless of the access modifiers of those members.
Instances of collection classes can be serialized into XML only if the classes implement either the IEnumerable or ICollection interface. The DataContractSerializer is much more likely to be able to serialize the instances of any pre-existing .NET type into XML without having to either modify the definition of the type or develop a wrapper for it.
Classes that implement the IDictionary interface, such as Hashtable, cannot be serialized into XML. It can translate into XML types like Hashtable that implement the IDictionary interface.
XmlSerializer does not support versioning. The DataContractSerializer incorporates some support for versioning.
XmlSerializer serializes a type by default is semantically identical to the XML. DataContractSerializer serializes a type, provided the namespace for the XML is explicitly defined.

What is REST & RESTful?

Representational State Transfer (REST) is introduced by Roy Fielding on 2000; it is an architectural style of large-scale networked software that takes advantage of the technologies and protocols of the World Wide Web. REST illustrate how concentrated data objects, or resources, can be defined and addressed, stressing the easy exchange of information and scalability.

In 2000, Roy Fielding, one of the primary authors of the HTTP specification, wrote a doctoral dissertation titled Architectural Styles and the Design of Network-based Software Architectures.

REST, an architectural style for building distributed hypermedia driven applications, involves building Resource-Oriented Architecture (ROA) by defining resources that implement uniform interfaces using standard HTTP verbs (GET, POST, PUT, and DELETE), and that can be located/identified by a Uniform Resource Identifier (URI).

REST is not tied to any particular technology or platform – it’s simply a way to design things to work like the Web. People often refer to services that follow this philosophy as “RESTful services.” WCF Services which is developed using REST architectural style is known as RESTFul Services.

WCF Services RESTFul Services
Endpoints have to create for each network protocol It can be connect over "Web" with HTTP request/response messages.
It works based on the Remote Procedural Call (RPC) It is working with HTTP's uniform interface
Service Reference has to add in the client applications No need to add the service reference in the client applications

What is the REST Starter Kit?

The WCF REST Starter Kit is a set of .NET Framework classes and Visual Studio features and templates that enable users to create and access REST-style Windows Communication Foundation (WCF) services. These services are based on the WCF web programming model available in .NET 3.5 SP1. The starter kit also contains the full source code for all features, detailed code samples, and unit tests.

Creating basic RESTFul Service

Step 1

Create a new WCF project using VS2010.

Language Visual C# or Visual Basic
Target Framework .NET Framework 4
Installed Templates WCF
Template WCF Service Application
Name RESTFulDemo

Step 2

Delete the existing IService1.cs & Service1.svc files and create two new files, IRESTService.cs & RESTService.cs.

Step 3

Create the person entity in the IService.cs (it can be created separately) and write a simple member for this entity. For DataContractSerialization decorate this class and member with DataContract & DataMember attributes. See the code below:

[DataContract]
public class Person
{
    [DataMember]
    public string ID;
    [DataMember]
    public string Name;
    [DataMember]
    public string Age;
}    

Person class and its members decorated with [DataContract] & [DataMember] using System.Runtime.Serialization namespace.

  • [DataContract] – An entity class which can be DataContractSerializable over the network.
  • [Datamember] – Only decorated with [Datamember] property can be serializable & also property of the class must be decorated with [DataContract]

Step 4

Create methods in IRESTService class and interface decorated with [ServiceContract] & its members decorated with [OperationContrat] using System.ServiceModel namespace.

[ServiceContract]
public interface IRestSerivce
{
    [OperationContract]
    Person CreatePerson(Person createPerson);

    [OperationContract]
    List<person> GetAllPerson();

    [OperationContract]
    Person GetAPerson(string id);

    [OperationContract]
    Person UpdatePerson(string id, Person updatePerson);

    [OperationContract]
    void DeletePerson(string id);
}     
  • [ServiceContract] - A service contract exposes class or interface to the client applications, which may contain one or more [OperationContract] methods.
  • [OperationContract] - Indicates that a method defines an operation that is part of a service contract in an application, i.e., only the method decorated with [OperationContract] is visible for WCF client application and class of this method must be decorated with [ServiceContract].

Step 5

Up to this level, code is similar to that normal WCF services, RESTful services works under HTTP protocol, as there is two important attributes WebGet & WebInvoke (System.ServiceModel.Web namespace) has to include for making this application as RESTful service.

WebGet and WebInvoke

WebGet operation is logically receiving the information from a service operation & it can be called by the REST programming model. The WebGet attribute is applied to a service operation in addition to the OperationContract and associates the operation with a UriTemplate as well as the HTTP protocol Get verb.

WebInvoke operation logically raises a service option & it can be called by the REST programming model. The WebInvoke attribute is applied to a service operation in addition to the OperationContract and associates the operation with a UriTemplate as well as an underlying transport verb that represents an invocation (for example, HTTP POST, PUT, or DELETE). WebInvoke has a property called Method, it allows specifying different types of HTTP methods (POST, PUT or DELETE), and by default Method is POST.

[ServiceContract]
public interface IRestSerivce
{
    //POST operation
    [OperationContract]
    [WebInvoke(UriTemplate = "", Method = "POST")]
    Person CreatePerson(Person createPerson);

    //Get Operation
    [OperationContract]
    [WebGet(UriTemplate = "")]
    List<person> GetAllPerson();
    [OperationContract]
    [WebGet(UriTemplate = "{id}")]
    Person GetAPerson(string id);

    //PUT Operation
    [OperationContract]
    [WebInvoke(UriTemplate = "{id}", Method = "PUT")]
    Person UpdatePerson(string id, Person updatePerson);

    //DELETE Operation
    [OperationContract]
    [WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
    void DeletePerson(string id);
}
     

Please see the modified code for IRESTService interface, WebGet & WebInvoke attributes decorates for methods available in the IRESTService interface.

Person CreatePerson(Person createPerson);
//It is basically insert operation, so WebInvoke HTTP POST is used

List<person> GetAllPerson();
Person GetAPerson(string id);
//These two methods retrieve the information, so WebGet (HTTP Get) is used

Person UpdatePerson(string id, Person updatePerson);
//This method updates the available information, so WebInvoke HTTP PUT is used

void DeletePerson(string id);
//This method deletes the available information, 
//so WebInvoke HTTP DELETE is used

Step 6

Implement the IRESTService in the RESTService class and complete the business requirements. Please see the sample code below:

public class RestSerivce : IRestSerivce
{
    List<person> persons = new List<person>();
    int personCount = 0;

    public Person CreatePerson(Person createPerson)
    {
        createPerson.ID = (++personCount).ToString();
        persons.Add(createPerson);
        return createPerson;
    }
    
    public List<Person> GetAllPerson()
    {
        return persons.ToList();
    }

    public Person GetAPerson(string id)
    {
        return persons.FirstOrDefault(e => e.ID.Equals(id));
    }

    public Person UpdatePerson(string id, Person updatePerson)
    {
        Person p = persons.FirstOrDefault(e => e.ID.Equals(id));
        p.Name = updatePerson.Name;
        p.Age = updatePerson.Age;
        return p;
    }

    public void DeletePerson(string id)
    {
        persons.RemoveAll(e => e.ID.Equals(id));
    }
}

Step 7

We have to make this service able to be run in ASP.NET compatibility mode, for this AspNetCompatibilityRequirements attributes have to decorate with the RESTService class.

[AspNetCompatibilityRequirements
	(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

public class RESTSerivce : IRestSerivce
{
    //Code Implementation
    //. . . . . .
    // . . . . . .
}

In the above RESTService class additionally decorated with ServiceBehavior attribute, it specifies internal behavior of a service operation.

Step 8

For using this RESTFul service application, this service has to host. So we need to be done below modification for running the RESTService.

Modifying the Web.Cogfig File

Remove all the code inside the <system.servicemodel> tag and insert the code below:

<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
</serviceHostingEnvironment>
    <standardEndpoints>
      <webHttpEndpoint>
        <standardEndpoint name="" helpEnabled="true" 
	automaticFormatSelectionEnabled="true"></standardEndpoint>
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>

<serviceHostingEnvironment> tag helps to run the applications in ASP.NET compatibility mode. <standardEndpoints> tag helps to get WebHelp for the RESTFul application.

Add Global.asax File

We can host RESTFul services using Global.asax file using the below code:

 RouteTable.Routes.Add(new ServiceRoute
	("RestService", new WebServiceHostFactory(), typeof(RESTSerivce)));    

Step 9

Run the RESTFulDemo application, it will be open in the explorer and address bar contain the base address of RESTFulDemo service.

http://localhost:XXXX/

Type the Routingprefix name “RestService” (string value given in the global.asax file).

http://localhost:XXXX/RestService - It is basically URI of the Get operation.

http://localhost:XXXX/restservice/help - It displays the help content for RESTFulDemo service.

Still we saw about creating and hosting the RESTFul services, next we have to consume this service, therefore we will see basic application to consume this RESTFulDemo service.

Consuming RESTFul Service

Step 1

Add a new console application to RESTFulDemo solution.

Language Visual C# or Visual Basic
Target Framework .NET Framework 4
Installed Templates WCF
Template Console Application
Name RESTClient

Step 2

do
{
    try
    {
        string content;
        Console.WriteLine("Enter Method:");
        string Method = Console.ReadLine();

        Console.WriteLine("Enter URI:");
        string uri = Console.ReadLine();

        HttpWebRequest req = WebRequest.Create(uri) as HttpWebRequest;
        req.KeepAlive = false;
        req.Method = Method.ToUpper();

        if (("POST,PUT").Split(',').Contains(Method.ToUpper()))
        {
            Console.WriteLine("Enter XML FilePath:");
            string FilePath = Console.ReadLine();
            content = (File.OpenText(@FilePath)).ReadToEnd();

            byte[] buffer = Encoding.ASCII.GetBytes(content);
            req.ContentLength = buffer.Length;
            req.ContentType = "text/xml";
            Stream PostData = req.GetRequestStream();
            PostData.Write(buffer, 0, buffer.Length);
            PostData.Close();
        }

        HttpWebResponse resp = req.GetResponse() as HttpWebResponse;

        Encoding enc = System.Text.Encoding.GetEncoding(1252);
        StreamReader loResponseStream = 
        new StreamReader(resp.GetResponseStream(), enc);

        string Response = loResponseStream.ReadToEnd();

        loResponseStream.Close();
        resp.Close();
        Console.WriteLine(Response);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message.ToString());
    }

    Console.WriteLine();
    Console.WriteLine("Do you want to continue?");
} while (Console.ReadLine().ToUpper() == "Y");

Step 3

Before running the RESTFulDemo application, set multiple startup projects. Please see the below image:

RUN the application. It will run the RESTFulDemo service as well as RESTClient console application.

HTTP GET Operation

Enter Method: Get
Enter URI: http://localhost:XXXX/restservice

It gives the XML output in the console screen.

HTTP POST Operation

Enter Method: Post
Enter URI: http://localhost:XXXX/restservice
Enter XML File Path: <enter input xml file path>

This operation creates a new person entity in the service, it can be seen in the browser by HTTP Get operation.

In the above screen, call the URI http://localhost:XXXX/restservice/1, URI ends with person ID (1). It calls the service operation.

[OperationContract]
[WebGet(UriTemplate = "{id}")]
Person GetAPerson(string id);

So it retrieves the person with ID 1.

Please refer to the attached project for detailed code.

Fiddler tool is more useful to test the RESTFul services.

Conclusion

I hope this article helps you to understand basic concept of RESTFul and that the reader is able to code to create & consume RESTFul service. Please let me know your valuable comments.

References

  1. http://msdn.microsoft.com/en-us/library/aa738737.aspx
  2. http://msdn.microsoft.com/en-us/netframework/dd547388
  3. http://msdn.microsoft.com/en-us/library/dd203052.aspx
  4. http://msdn.microsoft.com/en-us/library/system.servicemodel.web.webinvokeattribute.aspx
  5. http://msdn.microsoft.com/en-us/library/system.servicemodel.web.webgetattribute.aspx

License

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

About the Author

Arthanarieaswaran
Software Developer
India India
Member
Artha is a software developer in ASP.NET, C#.NET, VB.NET and ASP.
 
Microsoft Certified Professional Developer (MCPD) Microsoft ASP.NET Developer 3.5 (070-564)
 
Microsoft Certified Technology Specialist (MCTS) for Microsoft .NET Framework 3.5, ASP.NET Application Development (070-536, 070-562)
 
Microsoft Certified Professional (MCP) for Developing and Implementing Web Applications with Microsoft® Visual C#™ .NET and Microsoft® Visual Studio® .NET (070 315)
 
WIPO certification for General Course on Intellectual Property (DL-101)

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionServiceRoute is not working in my Global.asax filememberHiren Lad10 Apr '13 - 21:33 
Hi
I have go through your step. I have completed all the step. But i have not able to access System.ServiceModel.Activation.ServiceRoute Class.
 
RouteTable.Routes.Add(new ServiceRoute("RestService", new WebServiceHostFactory(), typeof(RestService)));
 
Get error near "new ServiceRoute" in above line. i have also import the new System.ServiceModel.Activation.
Can you please help me. Why i have not able to used ServiceRoute ???
 
Thanks
Hiren Lad
AnswerRe: ServiceRoute is not working in my Global.asax filememberArthanarieaswaran17 Apr '13 - 18:12 
Hi Hiren,
 

Please check whether you have System.ServiceModel, System.ServiceModel.Web and System.Web.Routing in your project.
 
Still you will get the error, please send the error details for further investigation.
 
Sorry for delayed reply.
 
Thanks and Regards
Artha
GeneralRe: ServiceRoute is not working in my Global.asax filememberNEOPOTTER22 Apr '13 - 5:20 
I think the only thing you should do is to add the System.ServiceMode.Activation.dll assembly reference from the Framework to your project that solves the issue.
QuestionNew get FunctionmemberMember 225651225 Feb '13 - 3:08 
Great article - my vote of 5
I have added a new get function as shown below: (I want to implement different functions)
[OperationContract]
[WebGet(UriTemplate = "/GetPerson?name={id}")]
Person GetPersonInfo(string id);
 
It only works if I call it from a browser with 'name=1'.
http://localhost:20949/restservice/GetPerson?name=1
What must you do if you only know the function GetPerson but not the parameter name?
AnswerRe: New get FunctionmemberArthanarieaswaran27 Feb '13 - 17:16 
Thanks for your comments.
You have to mention name&value pair for additonal function which you added, becuase URI http://localhost:20949/restservice/GetPerson/1 already pointing to some other method (GetAPerson).
So we cann't use single URI for pointing two method.
 
Please let know you, if you have any quries.
 
Thanks and Regards
Artha
GeneralMy vote of 5memberMember 225651225 Feb '13 - 3:01 
Just Great
GeneralMy vote of 5membersushil_k14 Feb '13 - 6:33 
Excellent article...Explained everything about REST and REstFull in detail....Thanks Sushil
GeneralRe: My vote of 5memberArthanarieaswaran27 Feb '13 - 17:00 
Thanks for your comments Sushil.
 
Artha
GeneralMy vote of 5memberNDhruve25 Jan '13 - 5:52 
Excellent article. My vote of 5 for putting efforts to write this detailed article. Great Job. Please keep it up.
GeneralRe: My vote of 5memberArthanarieaswaran27 Feb '13 - 16:59 
Thanks for your comments NDhruve.
 
Artha
QuestionMy Vote Of 5memberAlireza_136213 Dec '12 - 15:46 
Thanks for this useful article
Still not convinced why use step 8 ,Pleas Provide some good reasons to do that configuration
Thanks in advance
QuestionMy vote 5memberNitin Sawant5 Dec '12 - 17:23 
Excellent article on WCF. Thumbs Up | :thumbsup:
 
I wonder whether the new ASP.NET web API is replacement of WCF?
 
Thanks
============================================
The grass is always greener on the other side of the fence

AnswerRe: My vote 5memberArthanarieaswaran13 Dec '12 - 21:57 
Thanks for your comments Nithin.
 
RESTFul service is extension of WCF Service.
 
Thanks and Regards
Artha
QuestionIIS Settingmemberpcbaby154 Dec '12 - 18:43 
Hi Arth,
 
Thank you for the wonderful article.
It was a great jump start for me.
 
However, when I use the Routingprefix, my browser doesn't show anything.
Is there a setting in IIS that I need to configure?
 
I am just concern in case there is something wrong on my IIS settings.
 
Thanks a lot.
 
-Dantz
GeneralMy vote of 5memberRaisKazi3 Dec '12 - 3:39 
Nice article on REST.
GeneralRe: My vote of 5memberArthanarieaswaran13 Dec '12 - 21:49 
Thanks for your comments Raiskazi.
 

Artha
QuestionLarge Data and Streamingmembermenho20 Oct '12 - 10:21 
Great article Arthanarieaswaran, but i have a problem posting an image with REST, when image is more tha 64k it gives me an error: The remote server returned an error: (400) Bad Request.
At microsoft says to modify web.config like this:
«webHttpBinding»
«binding name="WebHttpBinding" maxReceivedMessageSize="10485760" maxBufferPoolSize="10485760" maxBufferSize="10485760" closeTimeout="00:03:00" openTimeout="00:03:00" receiveTimeout="00:10:00" sendTimeout="00:03:00" transferMode="StreamedRequest"»
«readerQuotas maxStringContentLength="10485760" maxArrayLength="10485760" maxBytesPerRead="10485760" /»
«security mode="None" /»
«/binding»
«/webHttpBinding»
but its not working.
AnswerRe: Large Data and StreamingmemberArthanarieaswaran28 Oct '12 - 18:44 
Hi Menho,
 
Please use '2147483647' instead of '10485760' in all the places inthe webHttpBinding and also increase all the time into '00:10:00'.
 
If still you get the error, give the details of the error you receive in the application.
 

Thanks and Regards
Arth
GeneralMy vote of 5memberdigimanus24 Sep '12 - 4:18 
helped me out of a problem
GeneralMy vote of 5membermendy aaron20 Sep '12 - 10:21 
Very clear and precise.
GeneralRe: My vote of 5memberArthanarieaswaran21 Sep '12 - 18:16 
Thanks for your comments Mendy Aaron.
 
Artha
GeneralGood articlememberRaghava Rao Mukkamala18 Sep '12 - 5:35 
Thanks. It worked prefectly!
GeneralRe: Good articlememberArthanarieaswaran19 Sep '12 - 18:26 
Thanks for your comments
QuestionDeploying REST WCF service on IISmemberSanta kotta11 Sep '12 - 5:25 
I was able to run the code you provided only from the Visual Studio debug server. I get either 404 or 403 forbidden error when I try to run it from IIS on my local host. Do I need to change any configuration settings?
Thanks
AnswerRe: Deploying REST WCF service on IISmemberArthanarieaswaran11 Sep '12 - 19:41 
Hi,
 
You have to append 'RestService' name at the end of the URI.
http://localhost/REST/restservice/
 
Thanks and Regards
Artha

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 23 Mar 2012
Article Copyright 2011 by Arthanarieaswaran
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid