Digging into WCF REST

Update: The recording for this talk is now available.

Last Thursday evening I presented a talk to the Dallas .NET User Group on support in WCF 4 for building REST-ful services. Here is a summary of the talk:

To REST or Not To REST? – Building REST-ful Services with the WCF Web Programming Model
REST is defined as an architectural style for building services that embrace the principles of the web. But what’s it good for? Tony will provide concrete examples of where it makes sense to implement REST-ful web services. He’ll also get down and dirty using the WCF Web Programming Model and show how WCF makes it easy to serve up POX or JSON, increasing the reach of your services to clients that don’t understand or care about SOAP. We’ll also look at API’s for syndicating content using RSS and ATOM.

Here are the slides and code for the talk, which highlighted improvements in WCF’s support for REST that arrived with .NET 4.0 and Visual Studio 2010, folding in features we first saw in the REST Starter Kit, which is now largely obsolete.

Here are some essential resources on WCF REST:

One of the things I highlighted in the talk is a Visual Studio template, which you can download from the Visual Studio Extensions Gallery, that creates a WCF REST-based service.  However, after installing the template, I was somewhat disappointed.  It creates a Visual Studio solution with just a single web project.  The service contract is merged with the implementation (just a class with no separate interface), and there is no client project.

About an hour before the talk, I decided to create my own version of the WCF REST Template, which creates a multi-project solution containing a web project with the service interface and class placed in a separate class library project and the entities in their own class library project.  I also threw in a console client project which consumes the WCF REST service and uses LINQ to XML to parse the results.  I was so pleased with the template, that I packaged it into a vsix project and uploaded it to the Visual Studio Extensions Gallery, so all you have to do is open up Visual Studio, go to Tools, Extension Manager, select Online Gallery and search for WCF REST Template.

ext-gallery

After installing the template, simply create a new project in Visual Studio, select the WCF category, and choose “WCF REST Service” from the list of project templates.

new-project

This will give you a solution containing four projects: An Entities project, containing a SampleItem class, a Service project, with an ISampleService interface implemented by a SampleService class, a Web project to host the service (which has a ReadMe file) and a Client project to consume the service.

sol-ex

All you have to do is set the Web project as the startup project for the solution and press Ctrl+F5 to launch the VS dev web server. Then set the Client project as the startup project and run it by pressing Ctrl+F5.  The client will issue an HTTP GET request to the service to retrieve XML representing a list of sample items. It uses LINQ to XML to parse the result into a list of items.

One of the things featured by the template is WCF 4’s simplified configuration model.  If you take a look at web.config, you’ll see that a default web http endpoint is configured to support a help page as well as automatic format selection (XML or JSON) based on the Content-Type and/or Accept HTTP headers.

rest-help

Typing the sample URI into the address of your browser will result in the following output:

get-collection

In addition, the template illustrates support in WCF 4 for using the ASP.NET url routing engine, in lieu of an .svc file.  You can see this in action if you take a peek at the code-behind for the global.asax file.

public class Global : HttpApplication {
    void Application_Start(object sender, EventArgs e)
    {
        RegisterRoutes();
    }

    private void RegisterRoutes()
    {
        // Edit the base address replacing the "SampleService" string below RouteTable.Routes.Add(new ServiceRoute("SampleService",
            new WebServiceHostFactory(), typeof(SampleService)));
    }
}

When an HTTP request arrives with a base address of SampleService (which you can change), the WebServiceHostFactory spins up the SampleService and maps the request to an operation, depending on the remaining part of the uri and the HTTP verb used.

// Start the service and browse to <a href="http://:/SampleService/help[ServiceContract]public">http://<machine_name>:<port>/SampleService/help [ServiceContract]
public interface ISampleService {
    [WebGet(UriTemplate = "")]
    List<SampleItem> GetCollection();

    [WebInvoke(UriTemplate = "", Method = "POST")]
    SampleItem Create(SampleItem instance);

    [WebGet(UriTemplate = "?id={id}")]
    SampleItem Get(int id);

    [WebInvoke(UriTemplate = "?id={id}", Method = "PUT")]
    SampleItem Update(int id, SampleItem instance);

    [WebInvoke(UriTemplate = "?id={id}", Method = "DELETE")]
    void Delete(int id);
}

This pattern also illustrates the resource-centric nature of a REST-based services architecture that leverages HTTP verbs for CRUD operations.  This architectural style comes in handy when you want to increase the reach of your service to clients that may not understand or care about SOAP, such as AJAX or Silverlight, or when you want to simplify the contractual footprint of your service by leveraging the uniform interface of the web and taking advantage of the HTTP protocol for things like security and caching.

I hope my WCF REST Template helps you get a better handle on building REST services with WCF. Enjoy.

About Tony Sneed

Married with three children.
This entry was posted in Technical and tagged . Bookmark the permalink.

20 Responses to Digging into WCF REST

  1. Pingback: Digging into WCF REST | Web, Programming, WCF, Security, ASP.NET, LINQ, XML, Ajax and Silverlight | Syngu

  2. Pingback: Build a Multi-Project Visual Studio Template | Tony Sneed's Blog

  3. Anonymous says:

    I have tried your code its work well at virtual machine.

    But my question is how to host it on local machine IIS 5.x and Windows XP.

    Please guide….

  4. Tony Sneed says:

    Glad you found it. You also might want to try IIS Express 7.5: http://learn.iis.net/page.aspx/901/iis-express-faq.

  5. dj says:

    I had some problems with deserialization (due to namespaces in xml).
    after adding Contract to SampleItem:

    [DataContract(Namespace = "", IsReference = false)]
    public class SampleItem
    {
    [DataMember]
    public int Id { get; set; }…

    one can simply deserialize:
    string xmlString2 = client.DownloadString(“SampleService?id=1″);
    XElement xml2 = XElement.Parse(xmlString2);

    XmlSerializer xs = new XmlSerializer(typeof(SampleItem));
    SampleItem obj = (SampleItem)xs.Deserialize(new StringReader(xmlString2));
    Console.WriteLine(“a: {0} {1}”, obj.Id, obj.StringValue)

  6. Ahmet Timuçin says:

    Hi Tony,

    Thank you for this great template.
    one request: Can you create this template for VB.NET also?
    one question: For deploying, there is another method using a SVC file using attribute Factory=”System.ServiceModel.Activation.WebServiceHostFactory” in the web project without using Global.asax. Is this one neater and a new way? Or is your way better?

    Regards,
    Ahmet.

    • Tony Sneed says:

      Yes, my way is better. :-) Well, not just because it’s my way, but in the world of REST you use plain old URI’s without the need for file extensions, including .svc. Using the ASP.NET routing module makes this possible and is definitely the way to go.

  7. Robert says:

    Great template, works like a charm!! I was wondering if you have an example on how to expand this template to expose a soap endpoint along side REST?

    Thanks!
    Robert.

    • Tony Sneed says:

      That’s a good suggestion. The built-in template for creating a soap-based WCF service is also poorly implemented. Not sure when I’ll have time to do it, but I’ll certainly put it on my list!

      Cheers,
      Tony

      • Robert says:

        That’s great, I’m having a hard time getting soap to work, tried various combinations. I’m hosting under IIS, created endpoints for rest/soap/mex, tried dozens of variations, but just can’t get it to work properly…

        Lots of fun :)

  8. Hiran says:

    This is a good starting point to work with REST services. I’m thinking of creating a JSON REST service using GET. the samples services you have shown here always get a primitive data type like integer or string. Would it be possible to have a object instance as a parameter instead of that?

    • Tony Sneed says:

      Actually, the sample service returns an array of complex objects (SampleItem). JSON is supported with the entry in web.config: automaticFormatSelectionEnabled=”true”. All you need to do for that is set the Accept or Content-Type header on the request to “application/json”. Try using Fiddler to create a request this way and you’ll see that JSON is returned.

      Cheers,
      Tony

      • Hiran says:

        Thanks Tony for the explanation. I’m more concerned about the request parameters. Would it be possible to have complex objects as request parameters?

      • Tony Sneed says:

        Yes, in fact if you look at the Create and Update methods in ISampleService, you’ll see that each accepts a SampleItem as a parameter. Create takes a POST request, while Update accepts a PUT request.

  9. Syed says:

    Brilliant article and well illustrated.
    I am thinking WCF REST in the domain driven design (DDD). Do you have some demo for it or how we can apply above SampleService in the DDD?

    Thanks
    Syed

    • Tony Sneed says:

      My take on this is that you would have one set of entities with data contracts and are returned by WCF REST services. You would then have another set of domain entities which encapsulate your business model and domain logic. Here is an article that might help:

  10. Syed says:

    Thanks Tony,
    You missed the article link…

  11. Racing Parts says:

    Oh my goodness! Impressive article dude! Many thanks, However I am having problems with your RSS. I don’t know the reason why I can’t subscribe to it. Is there anybody getting the same RSS issues? Anybody who knows the answer will you kindly respond? Thanks!!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s