Friday, July 11, 2014

REST in peace With Web services( from scratch )

REST  is stands for REpresentational State Transfer. REST is the underlying architecture of web.

It is basically the HTTP protocol, which was originally created to allow representational state transfer, not just transfer of web pages. HTTP is most commonly used to GET content and POST data. But it can also be used to PUT and DELETE data, as well as get Header information, etc

With this post I am going to create new web service that interact with data(xml) and going to make that web service into RESTFul web service

Create Web Service.  
 1. Open Visual Studio and goto -> New -> WCF -> WCF Service Application














2. Go to Solution explorer  and select two files IService1.cs and Service1.svc and delete them.(If you need you can keep them)















3. Then Press CTRL+SHIFT+A and Select Visual C# and WCF Service. Then give name for the service. Lets use it as demo_REST and Add














3. Lets open up the two files demo_REST.svc and demo_REST.cs and change its only funtion DoWork() to return string as output.

To do that first change the demo_REST.cs file's doWork as this.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace REST_Demo
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "Idemo_REST" in both code and config file together.
    [ServiceContract]
    public interface Idemo_REST
    {
        [OperationContract]
        string DoWork();
    }
}


Then go to the demo_REST.svc and edit it as follow. Just need to  change return type and add code to middle

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace REST_Demo
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "demo_REST" in code, svc and config file together.
    // NOTE: In order to launch WCF Test Client for testing this service, please select demo_REST.svc or demo_REST.svc.cs at the Solution Explorer and start debugging.
    public class demo_REST : Idemo_REST
    {
        //change public void DoWork() to public string DoWork()
        public string DoWork()
        {
            //add return text
            return "Hello WCF";
        }
    }
}



now we are done with our simple WCF

run and test it ..

its open in WCF test Client from WCF test Client select the function that we create DoWork() amd click on it then click on invoke button to test it



 In Value column it will display the results .. its "Hello WCF" and our function is working..


Implementing data bound Web service 
I am not going details about databounded web services. My previous article Web service with DB interaction provided good demonstration about how to work with DB data.

Here I am going to bind the XML file with it. I got the xml data from W3Schools (http://www.w3schools.com/xml/cd_catalog.xml)


In Visual Studio CTRL+SHIFT+A  then select Data and select XML File  and name it as cd_data.xml then copy paste the XML data from W3Schools to the XML body.

Now cd_data.xml is look likes this
<?xml version="1.0" encoding="utf-8" ?>
!-- Edited by XMLSpy --><CATALOG>
  <CD>
    <TITLE>Empire Burlesque</TITLE>
    <ARTIST>Bob Dylan</ARTIST>
    <COUNTRY>USA</COUNTRY>
    <COMPANY>Columbia</COMPANY>
    <PRICE>10.90</PRICE>
    <YEAR>1985</YEAR>
  </CD>
  <CD>
    <TITLE>Hide your heart</TITLE>
    <ARTIST>Bonnie Tyler</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>CBS Records</COMPANY>
    <PRICE>9.90</PRICE>
    <YEAR>1988</YEAR>
  </CD>
  <CD>
    <TITLE>Greatest Hits</TITLE>
    <ARTIST>Dolly Parton</ARTIST>
    <COUNTRY>USA</COUNTRY>
    <COMPANY>RCA</COMPANY>
    <PRICE>9.90</PRICE>
    <YEAR>1982</YEAR>
  </CD>
  <CD>
    <TITLE>Still got the blues</TITLE>
    <ARTIST>Gary Moore</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>Virgin records</COMPANY>
    <PRICE>10.20</PRICE>
    <YEAR>1990</YEAR>
  </CD>
  <CD>
    <TITLE>Eros</TITLE>
    <ARTIST>Eros Ramazzotti</ARTIST>
    <COUNTRY>EU</COUNTRY>
    <COMPANY>BMG</COMPANY>
    <PRICE>9.90</PRICE>
    <YEAR>1997</YEAR>
  </CD>
  <CD>
    <TITLE>One night only</TITLE>
    <ARTIST>Bee Gees</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>Polydor</COMPANY>
    <PRICE>10.90</PRICE>
    <YEAR>1998</YEAR>
  </CD>
  <CD>
    <TITLE>Sylvias Mother</TITLE>
    <ARTIST>Dr.Hook</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>CBS</COMPANY>
    <PRICE>8.10</PRICE>
    <YEAR>1973</YEAR>
  </CD>
  <CD>
    <TITLE>Maggie May</TITLE>
    <ARTIST>Rod Stewart</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>Pickwick</COMPANY>
    <PRICE>8.50</PRICE>
    <YEAR>1990</YEAR>
  </CD>
  <CD>
    <TITLE>Romanza</TITLE>
    <ARTIST>Andrea Bocelli</ARTIST>
    <COUNTRY>EU</COUNTRY>
    <COMPANY>Polydor</COMPANY>
    <PRICE>10.80</PRICE>
    <YEAR>1996</YEAR>
  </CD>
  <CD>
    <TITLE>When a man loves a woman</TITLE>
    <ARTIST>Percy Sledge</ARTIST>
    <COUNTRY>USA</COUNTRY>
    <COMPANY>Atlantic</COMPANY>
    <PRICE>8.70</PRICE>
    <YEAR>1987</YEAR>
  </CD>
  <CD>
    <TITLE>Black angel</TITLE>
    <ARTIST>Savage Rose</ARTIST>
    <COUNTRY>EU</COUNTRY>
    <COMPANY>Mega</COMPANY>
    <PRICE>10.90</PRICE>
    <YEAR>1995</YEAR>
  </CD>
  <CD>
    <TITLE>1999 Grammy Nominees</TITLE>
    <ARTIST>Many</ARTIST>
    <COUNTRY>USA</COUNTRY>
    <COMPANY>Grammy</COMPANY>
    <PRICE>10.20</PRICE>
    <YEAR>1999</YEAR>
  </CD>
  <CD>
    <TITLE>For the good times</TITLE>
    <ARTIST>Kenny Rogers</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>Mucik Master</COMPANY>
    <PRICE>8.70</PRICE>
    <YEAR>1995</YEAR>
  </CD>
  <CD>
    <TITLE>Big Willie style</TITLE>
    <ARTIST>Will Smith</ARTIST>
    <COUNTRY>USA</COUNTRY>
    <COMPANY>Columbia</COMPANY>
    <PRICE>9.90</PRICE>
    <YEAR>1997</YEAR>
  </CD>
  <CD>
    <TITLE>Tupelo Honey</TITLE>
    <ARTIST>Van Morrison</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>Polydor</COMPANY>
    <PRICE>8.20</PRICE>
    <YEAR>1971</YEAR>
  </CD>
  <CD>
    <TITLE>Soulsville</TITLE>
    <ARTIST>Jorn Hoel</ARTIST>
    <COUNTRY>Norway</COUNTRY>
    <COMPANY>WEA</COMPANY>
    <PRICE>7.90</PRICE>
    <YEAR>1996</YEAR>
  </CD>
  <CD>
    <TITLE>The very best of</TITLE>
    <ARTIST>Cat Stevens</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>Island</COMPANY>
    <PRICE>8.90</PRICE>
    <YEAR>1990</YEAR>
  </CD>
  <CD>
    <TITLE>Stop</TITLE>
    <ARTIST>Sam Brown</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>A and M</COMPANY>
    <PRICE>8.90</PRICE>
    <YEAR>1988</YEAR>
  </CD>
  <CD>
    <TITLE>Bridge of Spies</TITLE>
    <ARTIST>T'Pau</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>Siren</COMPANY>
    <PRICE>7.90</PRICE>
    <YEAR>1987</YEAR>
  </CD>
  <CD>
    <TITLE>Private Dancer</TITLE>
    <ARTIST>Tina Turner</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>Capitol</COMPANY>
    <PRICE>8.90</PRICE>
    <YEAR>1983</YEAR>
  </CD>
  <CD>
    <TITLE>Midt om natten</TITLE>
    <ARTIST>Kim Larsen</ARTIST>
    <COUNTRY>EU</COUNTRY>
    <COMPANY>Medley</COMPANY>
    <PRICE>7.80</PRICE>
    <YEAR>1983</YEAR>
  </CD>
  <CD>
    <TITLE>Pavarotti Gala Concert</TITLE>
    <ARTIST>Luciano Pavarotti</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>DECCA</COMPANY>
    <PRICE>9.90</PRICE>
    <YEAR>1991</YEAR>
  </CD>
  <CD>
    <TITLE>The dock of the bay</TITLE>
    <ARTIST>Otis Redding</ARTIST>
    <COUNTRY>USA</COUNTRY>
    <COMPANY>Atlantic</COMPANY>
    <PRICE>7.90</PRICE>
    <YEAR>1987</YEAR>
  </CD>
  <CD>
    <TITLE>Picture book</TITLE>
    <ARTIST>Simply Red</ARTIST>
    <COUNTRY>EU</COUNTRY>
    <COMPANY>Elektra</COMPANY>
    <PRICE>7.20</PRICE>
    <YEAR>1985</YEAR>
  </CD>
  <CD>
    <TITLE>Red</TITLE>
    <ARTIST>The Communards</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>London</COMPANY>
    <PRICE>7.80</PRICE>
    <YEAR>1987</YEAR>
  </CD>
  <CD>
    <TITLE>Unchain my heart</TITLE>
    <ARTIST>Joe Cocker</ARTIST>
    <COUNTRY>USA</COUNTRY>
    <COMPANY>EMI</COMPANY>
    <PRICE>8.20</PRICE>
    <YEAR>1987</YEAR>
  </CD>
</CATALOG>


Now we need to have some method to access those data n service. Open demo_REST.cs and inside the interface Idemo_REST add operation contract we named it as GetCatalog(). and we are going to return catalog data as JSON string then our return type for the GetCatalog() should be string.

namespace REST_Demo
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "Idemo_REST" in both code and config file together.
    [ServiceContract]
    public interface Idemo_REST
    {
        [OperationContract]
        string DoWork();
        //our newly added operation contract.
        [OperationContract]
        string GetCatelog();
    }
}

Lets implement the logic behind that interface function in Open demo_REST.svc 
 Now its look like this


public class demo_REST : Idemo_REST
  {
      //change public void DoWork() to public string DoWork()
      public string DoWork()
      {
          //add return text
          return "Hello WCF";
      }
      /// <summary>
      /// Code behind the Operation contract
      /// </summary>
      /// <returns></returns>
      public string GetCatelog()
      {
          //Read the XML File.. *You need to give XML file as URL
          XDocument xmlDataSheet = XDocument.Load("http://localhost:55173/cd_data.xml");
          //Get all items in XML file to the code
          var allItems = from data in xmlDataSheet.Descendants("CD")
                         select new
                          {
                              Title = data.Element("TITLE").Value,
                              Artist = data.Element("ARTIST").Value,
                              Country = data.Element("COUNTRY").Value,
                              Company = data.Element("COMPANY").Value,
                              Price = data.Element("PRICE").Value,
                              Year = data.Element("YEAR").Value
                          };
          //Json Serializer initiation
          JavaScriptSerializer toJson = new JavaScriptSerializer();
          //convert the data in the xml to list and convert them as JSON string
          return toJson.Serialize(allItems.ToList());
      }
  }


Run and check Our new addition is working or not.

Make It RESTful

 With our Web service Most hard part is done and now we nee to make our web service as restful service. For easyness of understanding the REST I'm using string parameter to the GetCatelog()
method Now its look like GetCatelog(string Parameter) in both Open demo_REST.cs and Open demo_REST.svc files.

To make our web service REST enable we need to add Web Invoked functionality to service. Lets consider  the HTTP GET here.

//our newly added operation contract.
       //We need output as json and input text is as json and our GET Url is /GetCatelog?para=textInput
       //Make sure you add correct parameter to correct input when working with multiple parameters
       //You can try different methods
       [OperationContract]
       [WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json,
          BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json,
          UriTemplate = "GetCatelog?para={Parameter}")]
       string GetCatelog(string Parameter);

Here is POST

[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "GetCatalog")]

Lets make it happen..

In final step you need to make sure few things configured correctly. configurations are on web.config file.

To make sure our endpoint of web service getting the JSON out put we need to add endpoint behavior to the web.config under <behaviors> tag

<!--End point json behavior-->
      <endpointBehaviors>
        <behavior name="jsonbehavior">
          <webHttp defaultBodyStyle="Wrapped" defaultOutgoingResponseFormat="Json"/>
        </behavior>
      </endpointBehaviors>

Under the <system.servicemodel> tag we need to add and configure our web service to enable HTTP (REST) and endpoint behaviors

<services >
    <!--adding service configuration-->
    <service name="REST_Demo.demo_REST"  >
      <endpoint
                address=""
                binding="webHttpBinding"
                behaviorConfiguration="jsonbehavior"
                contract="REST_Demo.Idemo_REST" />
    </service>
  </services>


We are done.. then run and test your service in browser
Here is my credentials. http://localhost:55173/demo_REST.svc/GetCatelog?para=text
 Result 






Full Code 
http://bit.ly/wcfREST

 

0 comments: