WCF 3.5: WebGet Attribute

11. September 2007 06:40

It has been a week or so since I contributed to my series on WCF 3.5.  Hopefully, I will get things back on track this week by focusing a bit on the new features that support the REST style of web services.  Rather than going into a long winded explanation of REST, I will defer to Wikipedia's definition.  The key take away for the purpose of this post is that REST is an alternative to the WS-* protocols and SOAP.  It places more of an emphasis on Plain Old Xml (POX) and HTTP methods (or verbs). 

We will kick things off by taking a look at one of the new attributes in WCF.  For those of your REST guys, this will be one of the most commonly used attributes for your services.  It is none other than WebGet, which resides in the System.ServiceModel.Web assembly.  As the name implies, this provides a mechanism to map an HTTP GET operation to a specific method.

Let's look at a simple example and break it down:

[ServiceContract(Namespace = "http://JeffBarnes.Samples.WeatherService")]
public interface IWeatherService
{
    [OperationContract]
    [WebGet(
        BodyStyle = WebMessageBodyStyle.Bare,
        RequestFormat = WebMessageFormat.Xml,
        ResponseFormat = WebMessageFormat.Xml,
        UriTemplate = "/GetCurrentTemp/{zipCode}")]
    Temperature GetCurrentTemperature(string zipCode);
}

If you examine the code, you will see a typical service contract and operation contract.  However, the WebGet attribute has also been applied to the same method as the operation contract.  This notifies the WCF runtime that the method is a retrieval operation and can be mapped to an HTTP GET operation.  The Temperature class returned by the method is a very simple class that contains a Scale and Amount property.  It is exposed via a standard DataContract.

As you can see, there are a few parameters available in the attribute.  They are relatively self-explanatory, but let's quickly review them. 

BodyStyle
This parameter indicates whether the request and response should be wrapped with "infrastructure provided XML elements."  This wrapping can be applied to both the request and response or only one of the two.  When set to Bare, there is no wrapping provided. 

Here is an example of a wrapped response from the GetCurrentTemperature method.

<GetCurrentTemperatureResponse xmlns="http://JeffBarnes.Samples.WeatherService">
  <GetCurrentTemperatureResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Amount>10.25</Amount> 
    <Scale>Celsius</Scale> 
  </GetCurrentTemperatureResult>
</GetCurrentTemperatureResponse>

Here is an example of a bare response from the GetCurrentTemperature method.

<Temperature 
   xmlns="http://JeffBarnes.Samples.WeatherService" 
   xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Amount>10.25</Amount> 
  <Scale>Celsius</Scale> 
</Temperature>

RequestFormat and ResponseFormat
These two parameters simply specify whether the request and response will be formatted as Xml or JSON.  Since there are two separate parameters, you could potentially have the request formatted differently from the response.

UriTemplate
At last, we finally begin to see where the new UriTemplate class comes into play.  This template provides a way to map the zip code in the uri to the zip code parameter in the GetCurrentTemperature method.  The beauty of this is that WCF takes care of the dirty work.  Rather than manually parsing out parameters from a uri, WCF just hands the value to the method.  Refer to my previous post about UriTemplate for more information.

Comments

9/12/2007 1:38:28 AM #

I wonder why the WCF team didn't decide to implement this using a new binding instead of an attribute (ie. RESTBinding).  Doesn't it seem like this is simply a different transport method?  And aren't transport methods specified as bindings?

Mike B. |

9/12/2007 9:08:03 AM #

Mike,

There is actually a new binding named WebHttpBinding that is required to support this functionality.  I just didn't cram all of the details into a single post.  Over the several posts, I plan to talk a bit more about the complete picture.  The WebGet attribute is only used to identify the method as a retrieval operation that allows it to be mapped to a specific uri.

jeff.barnes |

Comments are closed

About Me

I'm a passionate software developer and advocate of the Microsoft .NET platform.  In my opinion, software development is a craft that necessitates a conscious effort to continually improve your skills rather than falling into the trap of complacency.  I was also awarded as a Microsoft MVP in Connected Systems in 2008, 2009, and 2010.


Can’t code withoutThe best C# & VB.NET refactoring plugin for Visual Studio
Follow jeff_barnes on Twitter

View Jeff Barnes's profile on LinkedIn

 

Shared Items

Disclaimer

Anything you read or see on this site is solely based on my own thoughts.  The material on this site does not necessarily reflect the views of my employer or anyone else.  In other words, I don't speak for anyone other than myself.  So, don't assume I am the official spokesperson for anyone.