Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Tagged as

RESTful WCF Part 1 of n

, 9 Apr 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
Lately I have been neglecting my  coding duties a bit in order to go out and get drunk actually. Which I have become a bit tired of now, so I am back onto the code, which is a good place.Now I am in the process of creating another article, and though I can not reveal [...]

Lately I have been neglecting my coding duties a bit in order to go out and get drunk actually. Which I have become a bit tired of now, so I am back onto the code, which is a good place.

Now I am in the process of creating another article, and though I can not reveal what I am working on, as there is a competition involved, which I would like to have a pop at, I thought I may share bits of information about parts of it along the way.

I can say that I am using some new WCF stuff that came with .NET 3.5, namely the System.ServiceModel.Web namespace which allows us to create RESTful WCF services.

For those that do not know what REST is, here is what Wikipedia has to say about it.

"Representational state transfer (REST) is a style of software architecture for distributed hypermedia systems such as the World Wide Web. As such, it is not strictly a method for building "web services." The terms "representational state transfer" and "REST" were introduced in 2000 in the doctoral dissertation of Roy Fielding,[1] one of the principal authors of the Hypertext Transfer Protocol (HTTP) specification.

REST strictly refers to a collection of network architecture principles which outline how resources are defined and addressed. The term is often used in a looser sense to describe any simple interface which transmits domain-specific data over HTTP without an additional messaging layer such as SOAP or session tracking via HTTP cookies. These two meanings can conflict as well as overlap. It is possible to design a software system in accordance with Fielding’s REST architectural style without using HTTP and without interacting with the World Wide Web.[2] It is also possible to design simple XML+HTTP interfaces which do not conform to REST principles, and instead follow a model of remote procedure call. The difference between the uses of the term "REST" therefore causes some confusion in technical discussions.

Systems which follow Fielding’s REST principles are often referred to as "RESTful"."

http://en.wikipedia.org/wiki/Representational_State_Transfer

Basically what it means as a WCF developer is that you will expose resources which are accessible via Urls, which means all a client needs to use your service is a browser.

The schedule of posts is probably going to be something like this

  1. The new RESTful WCF attributes (this article)
  2. Serialization options
  3. Hosting
  4. CRUD operations using RESTful WCF

Ok so lets get on to some code.

This blog post will simply cover the new attributes that enable RESTful WCF.

In fact there is really only 2 attributes that in my mind are the lynchpins for the whole RESTful way of doing things using WCF. These attributes are

WebGetAttribute

"The WebGetAttribute attribute is applied to a service operation in addition to the OperationContractAttribute and associates the operation with a UriTemplate as well as the HTTP protocol Get verb. The association with HTTP Get verb means that the operation is used to retrieve information from the service. The WebGetAttribute attribute is a passive operation behavior (the IOperationBehavior methods do nothing) that adds metadata to the operation description. Applying the WebGetAttribute attribute to a service operation has no effect unless a behavior that is looking for this metadata in the operation description (such as WebHttpBehavior) is added to the service’s behavior collection."

MSDN

WebInvokeAttribute

"The WebInvokeAttribute attribute is applied to a service operation in addition to the OperationContractAttribute 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). The WebInvokeAttribute attribute is a passive operation behavior (the IOperationBehavior methods do nothing) that adds metadata to the operation description. Applying the WebInvokeAttribute attribute to a service operation has no effect unless a behavior that looks for this metadata in the operation description (such as WebHttpBehavior) is added to the service’s behavior collection. The WebInvokeAttribute determines what HTTP method that a service operation responds to. By default, all methods that have the WebInvokeAttribute applied respond to POST requests. The Method property allows you to specify a different HTTP method. If you want a service operation to respond to GET, use the WebGetAttribute instead."

MSDN

Let us now see some WCF code that uses one of these attributes. I am going to only discuss the usage of the WebGetAttribute in this post as I do not want to talk about all the CRUD operations that can be done with RESTful WCF just yet.

So in order to expose resources over a Url, we can use the WebGetAttribute to adorn our WCF service operations, here is an example

   1:  [ServiceContract(SessionMode = 
   2:      SessionMode.NotAllowed)]
   3:  public interface ISomeService
   4:  {
   5:  
   6:      [OperationContract]
   7:      [WebGet(UriTemplate = "/")]
   8:      Message GetRoot();
   9:  
  10:      [OperationContract]
  11:      [WebGet(UriTemplate = "/{userName}/")]
  12:      Message GetFavouriteBarsForUser(
  13:          String userName);
  14:  }

Notice that I have used the WebGetAttribute to adorn the WCF OperationContract methods. Also notice that there is a UriTemplate property which is set to either a root terminator "/" or has some more parts to the Url, where the extra parts of the Url are treated as method parameters, which allow more specific resources to be exposed.

In essence that is all there is to allowing a service to expose resources. Now we need to test this. In order to do that we need to implement this example service, so lets have a look at a small demo app I knocked up.

   1:  [ServiceBehavior(IncludeExceptionDetailInFaults = false, 
   2:      InstanceContextMode = InstanceContextMode.Single, 
   3:      ConcurrencyMode = ConcurrencyMode.Single)]
   4:  public class SomeService : ISomeService
   5:  {
   6:  
   7:      #region ISomeService Members
   8:  
   9:      public Message GetRoot()
  10:      {
  11:  
  12:          Message message = GetRootMessage();
  13:          return message;
  14:      }
  15:  
  16:  
  17:  
  18:      public Message 
  19:          GetFavouriteBarsForUser(string userName)
  20:      {
  21:          Message message = 
  22:              GetFavouriteBarsForUserMessage(userName);
  23:          return message;
  24:      }
  25:  
  26:      #endregion
  27:  
  28:      #region Private Methods
  29:  
  30:      /// <span class="code-SummaryComment"><summary></span>
  31:      /// Create bars for User message
  32:      /// <span class="code-SummaryComment"></summary></span>
  33:      private Message 
  34:          GetFavouriteBarsForUserMessage(String userName)
  35:      {
  36:          var stream = new MemoryStream();
  37:          XmlDictionaryWriter writer = 
  38:              XmlDictionaryWriter.CreateTextWriter(stream);
  39:          writer.WriteStartDocument();
  40:          writer.WriteStartElement("Root");
  41:          writer.WriteStartElement("Bar");
  42:          writer.WriteElementString("user", userName);
  43:          writer.WriteEndElement();
  44:          writer.WriteEndElement();
  45:          writer.WriteEndDocument();
  46:          writer.Flush();
  47:          stream.Position = 0;
  48:  
  49:          XmlDictionaryReader reader = 
  50:              XmlDictionaryReader.CreateTextReader(stream, 
  51:              XmlDictionaryReaderQuotas.Max);
  52:          return Message.CreateMessage(
  53:              MessageVersion.None, "", reader);
  54:      }
  55:  
  56:  
  57:      /// <span class="code-SummaryComment"><summary></span>
  58:      /// Create root message
  59:      /// <span class="code-SummaryComment"></summary></span>
  60:      private Message GetRootMessage()
  61:      {
  62:          var stream = new MemoryStream();
  63:          XmlDictionaryWriter writer = 
  64:              XmlDictionaryWriter.CreateTextWriter(stream);
  65:          writer.WriteStartDocument();
  66:          writer.WriteStartElement("Root");
  67:          writer.WriteStartElement("Hello");
  68:          writer.WriteElementString("Name", "sacha");
  69:          writer.WriteEndElement();
  70:          writer.WriteEndElement();
  71:          writer.WriteEndDocument();
  72:          writer.Flush();
  73:          stream.Position = 0;
  74:  
  75:          XmlDictionaryReader reader = 
  76:              XmlDictionaryReader.CreateTextReader(
  77:              stream, XmlDictionaryReaderQuotas.Max);
  78:          return Message.CreateMessage(
  79:              MessageVersion.None, "", reader);
  80:      }
  81:      #endregion
  82:  }

So you can see for each of the WebGetAttribute adorned WCF OperationContract methods, we will return a Message, which is really just some XML, which browsers will know how to display. If you don’t know what a Message Type is, do not worry we will be covering that in a subsequent post.

For now the important thing to note is that the service is exposing resources over REST using Urls.

The attached demo code includes a simply host, which when run will allow you to test various REST calls.

Here is what you need to do

  1. Run the simple host (SomeServiceTestConsole.exe)
  2. Open a browser and try the following Urls
    1. http://localhost:8085/SomeService
    2. http://localhost:8085/SomeService/sacha
    3. http://localhost:8085/SomeService/peter

And here is what you should see

http://localhost:8085/SomeService

image-thumb.png

http://localhost:8085/SomeService/sacha

image-thumb1.png

I hope you can see that by using these new RESTful attributes we can expose resources via Urls, which is accessable simply using a Browser. Of course to parse the XML there are many options.

Here is a small demo app that has a very simple RESTful service and a very simple Console host.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sacha Barber
Software Developer (Senior)
United Kingdom United Kingdom
I currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)
 
- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence
 
Both of these at Sussex University UK.
 
Award(s)

I am lucky enough to have won a few awards for Zany Crazy code articles over the years

  • Microsoft C# MVP 2014
  • Codeproject MVP 2014
  • Microsoft C# MVP 2013
  • Codeproject MVP 2013
  • Microsoft C# MVP 2012
  • Codeproject MVP 2012
  • Microsoft C# MVP 2011
  • Codeproject MVP 2011
  • Microsoft C# MVP 2010
  • Codeproject MVP 2010
  • Microsoft C# MVP 2009
  • Codeproject MVP 2009
  • Microsoft C# MVP 2008
  • Codeproject MVP 2008
  • And numerous codeproject awards which you can see over at my blog

Comments and Discussions

 
QuestionHeader add Pinmemberleszekzal21-Nov-14 13:23 
AnswerRe: Header add PinmvpSacha Barber21-Nov-14 21:30 
GeneralMy Five ... [modified] Pinmembersam.hill9-Apr-09 19:04 

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 | Terms of Use | Mobile
Web03 | 2.8.141216.1 | Last Updated 9 Apr 2009
Article Copyright 2009 by Sacha Barber
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid