Orcas Web Programming

The Orcas build of the .NET Framework will bring a lot of improvements to program for the Web. This means that you can expose your services in a fashion that makes it consumable by “simpler” web-enabled clients. It will use SOAP-less protocols, such as POX (Plain Old Xml), and give new encoding formats like JSON serialization. The latter ties in nicely with ASP.NET AJAX.

The goal for the Orcas Web programming API is to provide first class support for GET and POST requests. It will also allow the use of SOAP and POX from the same contracts and simplify caching and syndication. In a REST-ful architecture (a HTTP GET centric model) URIs are very important, as they convey not only endpoints, but also the payload of the messages. WCF did not have support for messages without SOAP envelopes built-in, but it will on the Orcas release of the .NET Framework.

Orcas Web-oriented features

These are the runtime components that make up the WCF features related to Web programming:

  • New contract annotations per operation for GET versus other HTTP verbs
  • A JSON serializer that transitions the DataContract to the JSON Infoset
  • Query string converter to parse a URI and an operation selector that will dispatch based on URIs and restricts the use to GET or selected HTTP verbs
  • JSON encoder for encoding messages to and from JSON format
  • New service hosts to facilitate IIS hosted services
  • Syndication API to construct and consume RSS and ATOM feeds.

Web operation dispatch conventions

Web programming endpoints will use prefix matching to map the URI prefix to a certain service object. The operations bind via a special template that describes the part of the URI to match. This template has one or more named placeholders that correspond to the input parameters of the operation. The templates and placeholders use the familiar { } pattern also used for positional parameters in string formatting. However, to denote the name of a parameter, names are used instead of integer index values. Read more on UriTemplate and Web programming on Steve Maine’s blog. The dispatching for a particular HTTP verb is determined by the use of either the WebGet or WebInvoke attribute. WebGet only allows dispatches of HTTP GET. WebInvoke takes care of the other verbs. The exact verb is specified in the Method property of WebInvoke.

The representational conventions for GET are that parameters are passed in the URI, giving you URLs ending like Rankings/{player}. This will match a URL such as http://localhost:8080/statistics/Rankings/Alex, where {player} will resolve to “Alex”. For other http verbs, e.g. POST, this information is passed in with the http body of the request.

If one of the URI templates matches the dispatch of a service request to an operation will succeed. From that point on the “normal” WCF infrastructure will kick in and use the serializers and encoders for JSON or POX.

Enough abstract talking. Let’s take a look at an example:

  [ServiceContract]

  public interface IGameStatistics

  {

    [OperationContract]

    [WebGet(UriTemplate = “Rankings/{player}”)]

    SyndicationFeedFormatter<SyndicationFeed> GetPlayerStats(string player);

 

    [OperationContract]

    [WebGet(ResponseFormat = WebMessageFormat.Json,

      UriTemplate = “PlayerSearch?GameType={gameType}&SortAscending={ascending}”)]

    Player[] Search(int gameType, bool ascending);

  }

The service contract above defines two operations, both of which are decorated with the WebGet attribute. You can see the UriTemplate for each of them. The PlayerSearch operation uses querystring parameters. These parameters must be specified as name=value pairs, like ASP.NET expects them as well.

Side note: If you happen to have used the Visual Studio 2008 Beta 1 of April 2007 or an older CTP, you may be surprised by the API changes. The old way used a HttpTransferContract attribute that took a Method and Path named parameter to specify the mapping of the HTTP verb and method to a service. BTW, the new API already appeared in the BizTalk Labs SDK, an early vehicle to ship the bits.

In the sample above, the Player class is defined as:

  [DataContract]

  public class Player

  {

    [DataMember]

    public string Name { get; set; }

    [DataMember]

    public int GameType { get; set; }

  }

Nothing special there, except for the new C# 3.0 automatic properties syntax that was used to define the two properties Name and GameType.

The service implementation of the first operation uses the syndication API and is the topic of a future post. The second service operation’s implementation is really trivial. However, what’s more interesting is the format of the result. As the format of the response message is specified as Json in the WebGet attribute, the result will now something like:

  [{“GameType”:1,“Name”:“LX”},{“GameType”:1,“Name”:“Paul[NL]”}]

for two Player objects that are returned on a http://localhost:8080/statistics/PlayerSearch?Gametype=1&SortAscending=true request. If you have never seen JSON before, you can see that it is ideal to pass into the JavaScript document.eval method. That will parse the JSON data and instantaneously return a JS object with properties and all. Aren’t dynamically types languages a beautiful thing?

Unless specified explicitly otherwise, the  request and response formats default to Xml for POX messages:

<ArrayOfPlayer xmlns=http://schemas.datacontract.org/2004/07/WCF35June2007 xmlns:i=http://www.w3.org/2001/XMLSchema-instance>

  <Player>

    <GameType>1</GameType>

    <Name>LX</Name>

  </Player>

  <Player>

    <GameType>1</GameType>

    <Name>Paul[NL]</Name>

  </Player>

</ArrayOfPlayer>

Hosting

WCF 3.5 has a new WebServiceHost class for hosting WCF services that have one or more endpoints with a WebHttpBinding. The main task of the specialized service host is to add a WebHttpBehavior to every endpoint using WebHttpBinding. Any ServiceDebug or ServiceMetadata behaviors will have their HTML help pages disabled. Of course the new host comes with a corresponding WebServiceHostFactory class to enable hosting from ASP.NET. The factory spits out a WebServiceHost and automatically sets a WebHttpBinding for every base address that starts with the schemes http or https. It then adds a WebHttpBehavior and sets the security mode to Transport for https endpoints.

  class Program

  {

    static void Main(string[] args)

    {

      Uri baseAddress = new Uri(http://localhost:8080&#8221;);

      using (WebServiceHost host = new WebServiceHost(typeof(StatisticsService), baseAddress))

      {

        WebHttpBinding webHttpBinding = new WebHttpBinding();

        ServiceEndpoint endpoint = host.AddServiceEndpoint(

                typeof(IGameStatistics), webHttpBinding, “Statistics”);

 

        host.Open();

 

        Console.WriteLine(“Service is up and running. Press ENTER to quit.”);

        Console.ReadLine();

      }

    }

You can read extra information on the differences between the normal ServiceHost and the WebServiceHost in this blog post by Justin Smith (who also has his book “Inside WCF” out).

Taking this one step further, there is also a WebScriptServiceHostFactory that creates a host (an internal class called WebScriptServiceHost) that behaves just like the WebServiceHost. The main difference is that the factory adds a WebScriptBehavior to every web-enabled endpoint. This behavior means that requests for the endpoint with /js added will return a JavaScript proxy for the service to be used with an AJAX website.

Wrap up

Essentially, what we get with the new WCF release is an implementation and infrastructure based on MessageVersion.None, which gets rid of all SOAP nastiness. It opens up the simpler standards such as JSON, POX to go REST on your service implementation. There’s more to be told on this. Stay tuned.

This entry was posted in Uncategorized. Bookmark the permalink.

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s