# Thursday, September 03, 2009

Developers have been using the REST specification for some time. If you are using Microsoft tools, ADO.NET Data Services aka Astoria is a very popular way to work with REST data. What you may not know is that Astoria works on top of WCF and you can write your own REST services outside of the Astoria model using WCF. WCF 3.5 SP1 gives us quite a few hooks to build our own RESTful services, however, it still takes a lot of manual wiring up by the developer. By now you all should know that I hate plumbing code.

Microsoft introduced the WCF REST Starter Kit, a set of WCF extensions and Visual Studio project templates to eliminate the plumbing code when building RESTful service with WCF. The five Visual Studio templates are:

  • REST Singleton Service
  • REST Collection Service
  • ATOM Feed Service
  • ATOMPub Service
  • HTTP Plain XML Service
  •  

    As explained in the developers guide to the WCF REST Starter Kit, the templates do the following:

    REST Singleton Service-Produces a service that defines a sample singleton resource (SampleItem) and the full HTTP interface for interacting with the singleton (GET, POST, PUT, and DELETE) with support for both XML and JSON representations.

    REST Collection Service-Similar to the REST Singleton Service only it also provides support for managing a collection of SampleItem resources.

    Atom Feed Service-Produces a service that exposes a sample Atom feed with dummy data.

    AtomPub Service-Produces a fully functional AtomPub service capable of managing collections of resources as well as media entries.

    HTTP Plain XML Service-Produces a service with simple GET and POST methods that you can build on for plain-old XML (POX) services that don’t fully conform to RESTful design principles, but instead rely only on GET and POST operations.

    While the REST Singleton is interesting, it is only useful if you are exposing one item, so the REST Collection is more suitable for interaction with a database driven dataset. The Atom Feed template is interesting but it is more useful if you are building feeds similar to RSS, so the AtomPub Service is more useful. The POX is a good option if you need to do something custom.

    While the REST WCF Starter Kit also provides some client libraries for easier interaction with your RESTful data, we will focus on the creation of the services.

    You can use Telerik OpenAccess as a data source of your REST Collection service. To do so you have to wire up some code in your svc file. Sound like a lot of work? Enter the OpenAccess WCF Wizard I wrote about before.

     

    If you create a project in Visual Studio to contain your data access layer and another to contain the REST Collection (using the new REST Collection template available from the WCF REST Starter Kit), you can point the Telerik WCF OpenAccess WCF Wizard at the data access layer project and then automatically generate the svc file and the corresponding CS file (shown by the arrow in our Visual Studio solution below.)

    image

    Just for a sanity check, let’s run our service by selecting the svc file and saying “view in browser”. You should see the RESTful XML representation as show below (make sure you turn off feed view in IE):

     image

    Now let’s consume this service from a Silverlight application. The WCF REST Starter Kit provides the developer with two classes, HttpClient and HttpMethodExtensions to help you consume the WCF RESTful service. Unfortunately they are not supported in Silverlight (or at least I can’t figure it out. :) )

    We’ll use plain old HTTPWebRequest instead.  But first I will create a grid in my XAML code like so:

    <data:DataGrid x:Name="dataGridCustomers" AutoGenerateColumns="False" ItemsSource="{Binding}">
        <data:DataGrid.Columns>
            <data:DataGridTextColumn Binding="{Binding Path=CompanyName}" Header="Company Name">
            </data:DataGridTextColumn>
            <data:DataGridTextColumn Binding="{Binding Path=ContactName}" Header="Contact Name">
            </data:DataGridTextColumn>
        </data:DataGrid.Columns>
    </data:DataGrid>

    I will create a LoadData() method to load the data on the page load or a “refresh” button event. Being Silverlight, of course we will use some asynchronous processing.

       1:  private void LoadData()
       2:  {
       3:      //address of your REST Collection service
       4:      string url= "http://localhost:60613/Customers.svc";
       5:      //set up the web resquest
       6:      HttpWebRequest rest = HttpWebRequest.Create(new Uri(url)) as HttpWebRequest;
       7:      //HTTP GET (REST uses the standard HTTP requests)
       8:      rest.Method = "GET";
       9:      //async callback
      10:      rest.BeginGetResponse(new AsyncCallback(ReadAsyncCallBack), rest);
      11:  }

     

    First we have to set a reference to our service in lines 4 & 6. Then we tell the HttpWebRequest to use an HTTP GET (line 8), this is the power of REST, it uses the standard HTTP requests (GET, POST, PUT, DELETE). On line 10 is where we begin our asynchronous call to ReadAsyncCallback() shown here.

       1:  private void ReadAsyncCallBack(IAsyncResult iar)
       2:  {
       3:      
       4:      //catch the HttpWebRequest
       5:      HttpWebRequest rest = (HttpWebRequest)iar.AsyncState;
       6:      HttpWebResponse response = rest.EndGetResponse(iar) as HttpWebResponse;
       7:      
       8:      var result = Customer.GetCustomersFromAtom10Stream(response.GetResponseStream());
       9:      //code block to handle the async call
      10:      this.Dispatcher.BeginInvoke( () =>
      11:          {
      12:              //build a collection (customers)
      13:              var customers = 
      14:                new System.Collections.ObjectModel.ObservableCollection<Customer>();
      15:              foreach (var customer in result)
      16:              {
      17:                  customers.Add(customer);
      18:              }
      19:              //bind to the grid when done
      20:              this.dataGridCustomers.DataContext = customers;
      21:          });
      22:  }

    ReadAsyncCallback() is the handler for the asynchronous call we did in LoadData(). We obtain a reference to the HttpWebRequest (lines 5-6) and then get the results back in line 8. Then we use a code block to build an ObservableCollection of Customers and fill them in a loop of the results (lines 15-18) and bind the data to the grid in line 20. The results are data binded to a grid as shown below.

    image

    Since Silverlight doesn’t support HTTP methods that do an update, we can’t do updates without a wrapper on the server. So we will stop the demo with just the read operation. Remember, if you are using a non-Silverlight client such as ASP.NET you can use the HttpClient and HttpMethodExtensions classes for an easier client coding experience.

    Grab the Telerik OpenAccess WCF Wizard here and the sample code from this blog post here.