Click here to Skip to main content
15,867,330 members
Articles / Programming Languages / C#

RESTful WCF - Part 1 of n

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
9 Apr 2009CPOL5 min read 27.8K   16   3
RESTful WCF

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 let's get on to some code.

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

In fact, there are 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:

C#
 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 let's have a look at a small demo app I knocked up.

C#
 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:      /// <summary>
31:      /// Create bars for User message
32:      /// </summary>
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:      /// <summary>
58:      /// Create root message
59:      /// </summary>
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

35281/image-thumb.png

http://localhost:8085/SomeService/sacha

35281/image-thumb1.png

I hope you can see that by using these new RESTful attributes, we can expose resources via URLs, which is accessible 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)


Written By
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 2016
  • Codeproject MVP 2016
  • Microsoft C# MVP 2015
  • Codeproject MVP 2015
  • 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 Pin
leszekzal21-Nov-14 12:23
leszekzal21-Nov-14 12:23 
AnswerRe: Header add Pin
Sacha Barber21-Nov-14 20:30
Sacha Barber21-Nov-14 20:30 
GeneralMy Five ... [modified] Pin
sam.hill9-Apr-09 18:04
sam.hill9-Apr-09 18:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.