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
Rate this:
Please Sign up or sign in to vote.

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
Technical Lead
India India
Artha is a Technical Lead in Windows Phone, WPF [MVVM, PRISM], ASP.NET [MVC 3.0 & 4.0], C#.NET, VB.NET and ASP.
 
Windows Phone
Microsoft Developer Network
 
Published Tools in Visual Studio Galleries
 
Published Source Codes in CodePlex
 
Microsoft Virtual Academy Profile
 
Published Articles in Code Project
 
Microsoft Certified Professional Developer (MCPD) Microsoft ASP.NET Developer 3.5 (070-564, 070-536, 070-562, 070 315)

Comments and Discussions

 
QuestionSeveral Questions and Suggestions Pinmemberjroughgarden2-Apr-14 10:11 
QuestionType 'ServiceRoute' is not defined PinmemberEd_lon27-Mar-14 14:54 
QuestionGetting error PinmemberRapsy Tree11-Feb-14 23:21 
AnswerRe: Getting error PinmemberArthanarieaswaran12-Feb-14 23:45 
GeneralRe: Getting error PinmemberRapsy Tree13-Feb-14 2:02 
GeneralRe: Getting error PinmemberJaswanth Reddy12-Mar-14 20:55 
GeneralReally Helpful.. Great Work Pinmemberyog24025-Dec-13 22:01 
GeneralRe: Really Helpful.. Great Work PinmemberArthanarieaswaran26-Dec-13 4:01 
QuestionExcellent Article. PinmemberSteve Bangalore21-Nov-13 10:43 
AnswerRe: Excellent Article. PinmemberArthanarieaswaran21-Nov-13 16:18 
QuestionGreat article - A related question PinmemberSimbarasheM31-Oct-13 6:43 
AnswerRe: Great article - A related question PinmemberArthanarieaswaran4-Nov-13 16:46 
GeneralRe: Great article - A related question PinmemberSimbarasheM4-Nov-13 19:02 
GeneralVote PinmemberSwarup Batabyal26-Oct-13 2:07 
GeneralRe: Vote PinmemberArthanarieaswaran29-Oct-13 16:22 
QuestionIn depth comparison PinmemberHiteshforu200716-Sep-13 2:49 
AnswerRe: In depth comparison PinmemberArthanarieaswaran16-Sep-13 17:44 
BugCoding Misplaced PinmemberMember 877568311-Sep-13 21:53 
GeneralRe: Coding Misplaced PinmemberArthanarieaswaran11-Sep-13 22:30 
GeneralRe: Coding Misplaced PinmemberMember 877568312-Sep-13 0:36 
GeneralRe: Coding Misplaced PinmemberArthanarieaswaran12-Sep-13 0:56 
GeneralRe: Coding Misplaced PinmemberMember 877568312-Sep-13 1:09 
GeneralRe: Coding Misplaced PinmemberArthanarieaswaran12-Sep-13 1:32 
GeneralRe: Coding Misplaced PinmemberMember 877568312-Sep-13 1:40 
GeneralRe: Coding Misplaced PinmemberMember 877568312-Sep-13 1:54 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

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