Creating RESTful Services Using WCF

A question popped up on an internal email distribution list today about how to expose a WCF service using WebGet and how to post POX (plain old XML) to that service using the .NET 3.5 WebInvoke attribute.  That part's easy, but the harder part is figuring out how to use Fiddler as a client to invoke the service.  If you aren't using Fiddler yet, run and download it... seriously, I'll wait here while you go do that right now.

REST in WCF 3.5

There's a lot to the web programming model in .NET 3.5.  Lemme 'splain... no, there is too much, lemme sum up.  .NET 3.5 supports a RESTful programming model, also known as a web programming model, using WCF.  It is really slick in that you can use HTTP GET for services by applying a WebGet attribute to your method.  Similarly, you can use the other HTTP verbs (10 points to anyone who correctly identifies the others that aren't POST) using the WebInvoke attribute.  Both of these attributes allow you to control the URI through a feature called a UriTemplate, basically a placeholder for portions of the URI.

To build this sample, I started by going to the MSDN documentation and found the topic "How to: Create a Basic Web-Style Service."  That sample is a good start, but I wanted to show how to use complex types and UriTemplates.  I modified it just a bit, and presto:  instant RESTful service.

 using System.ServiceModel;
using System.ServiceModel.Web;
using System.Runtime.Serialization;

namespace Microsoft.WebProgrammingModel.Samples
{
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        [WebGet(UriTemplate="customers/{id}")]
        Customer GetCustomer(string id);

        [OperationContract]
        [WebInvoke(UriTemplate="customers")]
        Customer PostCustomer(Customer c);
    }


    public class Service : IService
    {
        public Customer GetCustomer(string id)
        {
            return new Customer { ID = id, Name = "Demo User" };
        }

        public Customer PostCustomer(Customer c)
        {
            return new Customer { ID = c.ID, Name = "Hello, " + c.Name };
        }
    }


    [DataContract(Namespace="")]
    public class Customer
    {
        [DataMember]
        public string ID { get; set; }
        [DataMember]
        public string Name { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Uri baseAddress = new Uri("https://127.0.0.1:8000");

            using (WebServiceHost host = new WebServiceHost(typeof(Service), baseAddress))
            {
                host.Open();
                Console.WriteLine("Press any key to terminate");
                Console.ReadLine();
            }
        }
    }
}

Now, the hard part... copy it into a Console app, add references for System.ServiceModel, System.Runtime.Serialization, and System.ServiceModel.Web, and hit F5 in Visual Studio. 

Calling a RESTful Service Using Fiddler

Once it's running, how do you actually use this service?  Turns out, it's simple.  The method decorated with the WebGet attribute enables this to be called with a simple HTTP GET verb, which you can enter into your browser's URL and see how to use:

https://127.0.0.1:8000/customers/2

The trickier part is understanding how to use HTTP POST.  The URI is straightforward, we are going to be posting to:

https://127.0.0.1:8000/customers

What's tricky is determining what to put in the HTTP headers and the request body.  We need to define the content type that we are going to POST to the service, in our case it is the MIME type application/xml.  We should also define the content length in the HTTP header before sending to the service. 

As for what to put in the request body, that part is easy... that's our Plain Old XML (POX) that we want to post to the service.  The Customer type that I defined before explicitly uses an empty string for the namespace, which makes forming the request body just a little easier.  You can see a screen shot of Fiddler below:

Building RESTful web services with WCF is scary easy.

For more information:

Zen of the Web Programming Model (Part 1)

HTTP/POX Programming Basics

WebServiceHost vs ServiceHost

Creating a JSON Service with WebGet and WCF 3.5

Using WCF WebHttpBinding and WebGet with nicer Urls

Picture Services shows off WCF Web Programming

Podcast with Jon Udell