Pedro Félix’s shared memory

WCF Web API–Processing Architecture

Posted in Software by pedrofelix on April 26, 2011

This is the sixth post on a series about the new Preview 4 of WCF Web API. The previous posts were:

This post aims to present the processing architecture: what happens since a HTTP request message is received by the WCF Web API runtime until the HTTP response bytes are written into the transport layer.

The following description reflects my understanding of the WCF Web API runtime, based on the source code, and may not be completely accurate. Comments and corrections are greatly appreciated.

0. The big picture

The following diagram aims to schematize the HTTP request processing architecture.

Runtime2

In the bottom layer is the interface between the WCF runtime and the transport layer, namely the transport channel and the message encoder/decoder. The resource class, composed by a set of operations that handle HTTP requests and produce HTTP responses (for more details, see the first post), is at the top layer.

1. From bytes to HttpRequestMessage

The journey begins at the bottom layer, where a sequence of bytes obtained from the transport protocol is transformed into a HttpRequestMessage instance by WCF’s transport channel and message encoder/decoder.

2. Message handlers

After creation, the HttpRequestMessage instance passes through a sequence of message handlers. Each one of this message handlers receives an HttpRequestMessage and returns a HttpResponseMessage asynchronously. Being more precise, the message handlers expose the following method

Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

 

Each message handler has a reference to the next handler in the sequence, called the inner handler. A typical usage scenario is for the handler to perform some processing over the request message (e.g. read an header and add a property to the message, change the request method) and then forward it to the inner handler. After the inner handler returns the response, then another processing can be done over this response message (e.g. add an header) before it is returned.

MessageHandler.Passthrough

Another usage scenario is for the handler to produce the response message immediately and return it without forwarding the request to the inner handler. This means the the upper layers of the runtime will not be called, namely the resource class.

MessageHandler.Stop

For a concrete example of these two scenarios, consider a channel that implements HTTP Basic Authentication:

  • The SendAsync method inspects the request message to see if it contains an Authorization header with valid credentials. If so, it adds a property with the user’s identity to the message and lets the request flow to the inner handler. In this case, the handler’s return will be the inner handler’s return.
  • If the Authorization header does not exists or has invalid credentials, then a 401 response message is created with a WWW-Authenticate header. This response message is returned immediately, that is,  the inner handler is not called – the request processing is short-circuited.

The message handlers provide an asynchronous interface that, given a HttpRequestMessage, returns a Task<HttpResponseMessage>. This means that message handlers are an adequate place to perform lengthy I/O operations without blocking the processing thread. Using the above concrete example, implementing HTTP Basic Authentication, this I/O operation can be the retrieval of the user’s roles from an external service/resource/database.MessageHandler.IO

For a concrete example of a message channel, see http://weblogs.asp.net/cibrax/archive/2011/04/15/http-message-channels-in-wcf-web-apis-preview-4.aspx. Note that currently message handlers are still called message channels.

3. Dispatching

If the request message survives all the message handlers, the next phase in the request processing is the operation dispatch. In this phase, the request’s method and URI are used to select the operation that will be called. This selection uses the operation’s WebGetAttribute or WebInvokeAttribute to obtain the operation’s method and URI template. The request is then forwarded to the selected operation, via the operation handlers.

If no operations matchs the request, then a 404 response is produced.

4. Operation Handlers

The next processing phase is responsible for producing the parameter set required by the selected operation, from the request message. This parameters are produced by operation handlers. These operation handlers may also be used to perform other type of operation specific message processing (e.g. operation caching).

Message handlers receive a request message and produce (asynchronously) a response message. Operation handlers, on the other hand, receive a set of parameters and produce (synchronously) another set of parameters. These parameters are described by the HttpParameter class, namely

  • by a name;
  • and by a type.

There is another difference between message handlers and operation handlers: message handlers apply to every request; operation handler apply only to the operation where they where added. This is illustrated in the first diagram: there is one message handler “stack” and multiple operation handlers “stacks”.

Each operation handler derives from the HttpOperationHandler class and must implement the following methods:

  • OnGetInputParameters – returns an IEnumerable<HttpParameter> with the parameters that the handler wants to receive.
  • OnGetOutputParameters – returns an IEnumerable<HttpParameter> with the parameters that the handler produces.
  • OnHandle – receives an object[] with the input parameter’s values and returns another object[] with the output parameter’s values.

Each operation handler receives parameters from a parameter bag (input parameters) and contribute with parameters to that bag (output parameters).

OperationHandlers

Initially, this bag is populated with the request message itself. Afterwards, the OnHandle method of each handler is executed, resulting in more parameter values added to the bag.

The operation handlers are execution by an order that satisfies the handler’s dependencies: when a given handler executes, all of its input parameters must already be in the bag, produced by previously executed handlers. This execution order is determined during service startup, based on the input and output characterization of each handler (OnGetInputParameters and OnGetOutputParameters).

The execution order must also guarantee that, at the end of this phase, all the operation’s input parameters are  available in the bag.

If this order does not exists, e.g. an operation handler or the operation uses a parameter that isn’t provided by any other handler, then a runtime error occurs.

An example operation handler was showed in the third post.

Another interesting operation handler to analyze is the UriTemplateHandler. This handler, added automatically by the WCF Web API runtime, receives the request messaged and matches the operation’s URI template with the request URI. Then, it outputs one parameter for each bound variable. This is the way how variables are extracted from the URI, both from the path and from the query string, and turned into operation’s parameters.

5. Instance creation

Before the operation is called, a resource class instance is obtained – operations are instance methods.

It is possible to plugin a custom instance provider for obtaining these instances. A typical scenario is the use of an IoC/DI container for that purpose.

6. Operation invoke

Finally, at the topmost layer, the operation is invoked using the parameters computed by the operation handlers.

7. Response operation handlers

After the operation’s invocation, the output parameters pass through a sequence of response operation handlers. One of the most interesting things happening in this phase is the content encoding, which will be the subject of another post.

Also, if the response message was not returned by the operation, it is created in this phase

Finally, the response message flows down through the message handlers until being turned into a byte sequence and written into the transport layer.

Concluding remarks

  • This post does not describe how custom message or operation handlers are added to the runtime. This will be the subject of a future post about configuration.
  • In the following posts I will also present in more detail some of the described phases.
  • Once again: comments, corrections and suggestions are welcomed.
Tagged with: ,

WCF Web API–HTTP Message classes

Posted in Software by pedrofelix on April 23, 2011

This is the fifth post on a series about the new Preview 4 of WCF Web API. The previous posts were:

In this post, I briefly present the HTTP message classes, which are at the core of the WCF Web API processing model.

The following diagram shows the main classes for representing both requests and responses.HttpMessages

  • The two main classes are HttpRequestMessage, representing a HTTP request; and HttpResponseMessage, representing a HTTP response.
  • Both HttpRequestMessage and HttpResponseMessage have a Content property, of type HttpContent (abstract class) that represents the message’s body. Some available concrete content classes are
    • ByteArrayContent;
    • StringContent;
    • FormUrlEncodedContent;
    • StreamContent.
  • There are three different classes for message header representation
  • These classes are composed by a set of properties, one for each represented header. This allow for an easier access to headers (e.g. someRequest.Headers.Accept).
  • Note that the entity-headers are referenced by the content class and not directly by the request or response classes.
  • Note also that both the request’s Method and the response’s StatusCode are classes/enums and not just strings or integers.
  • Both HttpRequestMessage and HttpResponseMessage are concrete classes with public constructors, allowing for their simple instantiation, namely in testing scenarios.
  • Despite their core role in the HTTP Web API, these message classes belong to a different assembly – Microsoft.Net.Http.
Tagged with: ,

WCF Web API–IIS Hosting

Posted in Software by pedrofelix on April 22, 2011

This is the fourth post on a series about the new WCF Web API – Preview 4.

In the second post, I described how to create self hosted services. In this post, I’ll show how to host on IIS.

1. Create a empty ASP.NET web application and map a IIS site or virtual directory into it. On my development environment, I usually create a new site for each project and use the hosts file to map the site name to 127.0.0.1.

2. Ensure the following on the web.config

  <!-- Ensure the UrlRoutingModule -->
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule"
               type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
  </system.webServer>

  <!-- Enable ASP.NET compatibility -->
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  </system.serviceModel>

The UrlRoutingModule is used to route the requests into the WCF runtime.

3. Add the following route map to the application start (global.asax)

public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        ...
        RouteTable.Routes.MapServiceRoute&lt;TodoResource&gt;("todos");
        ...
    }
}

where TodoResource is the resource class (service class) and “todos” is the base path.

The MapServiceRoute extension methods adds a ServiceRoute to the RouteTable.Routes collection. This ServiceRoute uses a host factory that will produce a HttpConfigurableServiceHost. This host derives from the new HttpServiceHost, introduced on a previous post.

The MapServiceRoute also accepts an IHttpHostConfigurationBuilder, which can be used to configure the service. This configuration model, also applicable to self-hosting scenarios, will be the subject of a future post.

Tagged with: ,

WCF Web API – Self-hosting, HTTPS and HTTP Basic Authentication

Posted in Software by pedrofelix on April 21, 2011

(Edited on 02/26/2012: WCF Web API is now ASP.NET Web API, which introduced some breaking changes. However, I’ve a new post describing how to enable HTTPS with self-hosting, on the ASP.NET Web API Beta)

(Edited on 09/24/2011: There is a new version of the code below, for the Preview 5 release. The major changes are on the configuration model.)

This is the third post on a series about the new WCF Web API – Preview 4.

In the last post, I described how to create self hosted services. In this post, I show how to use HTTPS and Basic Authentication for these services.

Self-hosting and HTTPS

Both self-hosting and IIS-hosting use the HTTP.sys windows component for HTTP request listening. This HTTP.sys component handles the transport level issues, such as the SSL protocol.

One of the configurations that must be done at the HTTP.sys level is the definition of the server certificate and private key, since the SSL protocol handshake is performed by this component.

When using IIS, the HTTP.sys configuration is done via the IIS manager. However, when self-hosting, the netsh command line utility must be used.

So, the first step is to register the server side certificate using the following command

netsh http add sslcert ipport=0.0.0.0:port certhash=thumbprint appid={app-guid}

where

  • port is the listening port (e.g. 443); the special IP address 0.0.0.0 matches any IP address for the local machine;
  • thumbprint is the certificate’s SHA-1 hash, represented in hexadecimal;
  • app-guid is any GUID, used to identity the owning application.

This command allows for other optional parameters, such as clientcertnegotiation, that define complementary SSL aspects.

For more information about this subject, I recommend:

Endpoints and HTTPS

In order for a WCF endpoint to use HTTPS, instead of plain HTTP, the endpoint’s binding must be properly defined. The new HttpBinding has a constructor overload that receives an HttpBindingSecurityMode. The options are:

  • None – no security;
  • Transport –both authentication and transport level protection, i. e., HTTPS;
  • TransportCredentialOnly – only authentication.

Endpoints and HTTP Basic Authentication

The authentication mechanism (e.g. HTTP Basic Authentication or client certificates) is also defined at the binding, via the Security.Transport.ClientCredentialType property.

The credential validation policy, username and password in the case of HTTP Basic Authentication, is defined at the service host, using the Credentials.UserNameAuthentication property.

The following code excerpt shows both the binding and host configuration.

using (var host = new HttpServiceHost(typeof(TheResourceClass), new string[0]))
{
    var binding = new HttpBinding(HttpBindingSecurityMode.Transport);
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
    var ep = host.AddServiceEndpoint(typeof(TheResourceClass),
                                                             binding,
                                                             "https://localhost:8435/greet");
    ep.Behaviors.Add(new HttpBehavior()
        {
            OperationHandlerFactory = new MyOperationHandlerFactory()
        });
    host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode =
    UserNamePasswordValidationMode.Custom;
    host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new MyCustomValidator();
    host.Open();
    Console.WriteLine("Service is opened, press any key to continue");
    Console.ReadKey();
}

The custom validator derives from UserNamePasswordValidator

class MyCustomValidator : UserNamePasswordValidator
{
    public override void Validate(string userName, string password)
    {
        if(!credentials are valid)
            throw new FaultException("Unknown Username or Incorrect Password");
    }
}

Accessing the user’s identity

The final issue regards the access to the user’s identity, obtained from the authentication process.  It would be nice if the request handling operation could receive this information as a parameter.

[ServiceContract]
class TheResourceClass
{
    [WebGet(UriTemplate = "")]
    HttpResponseMessage GetGreetings(IPrincipal principal)
    {
        return new HttpResponseMessage()
        {
            StatusCode = HttpStatusCode.OK,
            Content = new StringContent("hello "+principal.Identity.Name)
        };
    }
}

In above example, the GetGreetings operation receives an IPrincipal with the user’s identity. This parameter is injected into the operation by an operation handler, which is a new WCF Web API concept.  This new concept alone deserves one or more future posts, so here I will only present the required code.

class PrincipalFromBasicAuthenticationOperationHandler : HttpOperationHandler<HttpRequestMessage,IPrincipal>
{
    public PrincipalFromBasicAuthenticationOperationHandler() : base("Principal") { }

    public override IPrincipal OnHandle(HttpRequestMessage input)
    {
        if (input.Headers.Authorization == null || input.Headers.Authorization.Scheme != "Basic")
        {
            // If properly configured, this should never happen:
            // this OperationHandler should only be used when
            // Basic authorization is required
            throw new HttpResponseException(HttpStatusCode.InternalServerError);
        }
        var encoded = input.Headers.Authorization.Parameter;
        var encoding = Encoding.GetEncoding("iso-8859-1");
        var userPass = encoding.GetString(Convert.FromBase64String(encoded));
        int sep = userPass.IndexOf(':');
        var username = userPass.Substring(0, sep);
        var identity = new GenericIdentity(username, "Basic");
        return new GenericPrincipal(identity, new string[] { });
    }
}

The above operation handler extracts the user name from the “Authorization” header, whose credentials were previously validated via the custom validator, and creates a GenericPrincipal with that name.

Next, an operation handler factory is required to register this new operation handler.

class MyOperationHandlerFactory : HttpOperationHandlerFactory
{
    protected override Collection<HttpOperationHandler> OnCreateRequestHandlers(ServiceEndpoint endpoint, HttpOperationDescription operation)
    {
        var coll = base.OnCreateRequestHandlers(endpoint, operation);
        if (operation.InputParameters.Any(p => p.Type.Equals(typeof(IPrincipal))))
        {
            var binding = endpoint.Binding as HttpBinding;
            if (binding != null && binding.Security.Transport.ClientCredentialType == HttpClientCredentialType.Basic)
            {
                coll.Add(new PrincipalFromBasicAuthenticationOperationHandler());
            }
        }
        return coll;
    }
}

Notice that the PrincipalFromBasicAuthenticationOperationHandler is only inserted if the operation requires an IPrincipal and the endpoint is using HTTP Basic Authentication.

Finally, the factory is configured into the HttpBehavior used when defining the endpoint.

var ep = host.AddServiceEndpoint(typeof(TheResourceClass), binding, "https://localhost:8435/greet");
ep.Behaviors.Add(new HttpBehavior()
    {
        OperationHandlerFactory = new MyOperationHandlerFactory()
    });

Concluding remarks

  • Security is one of the WCF Web API where more changes are expected in the future. For example, the current sample uses the built in support for HTTP Basic Authentication provided by the “old” WCF HTTP transport channel. In the future, this functionality may be provided by other means (e. g. via a HttpMessageChannel/HttpMessageHandler).
  • Configuration is another area expected to change in the future. In this sample, I configure the endpoint directly, via the HttpBehavior. In the future, this may not be the preferred or adequate way to do this.
  • Unfortunately, the way Basic Authentication is currently implemented by the transport channel has the following issue: after the first invalid (username, password) pair, the response will be 403 and not 401. This means that the password would not be requested again by a typical user-agent. See  http://blogs.msdn.com/b/drnick/archive/2010/02/02/fix-to-allow-customizing-the-status-code-when-validation-fails.aspx for more details.
Tagged with: ,

WCF Web API–Self-hosting

Posted in Software by pedrofelix on April 20, 2011

This is the second post on a series about the new Preview 4 of WCF Web API. In the previous post, I introduced the elementary aspects of the programming model, namely: resource classes, operations, HttpRequestMessage and HttpResponseMessage. The main outcome of the post was the TodoResource class.

In this post, I describe how to self-host this class. Lets the code do the talking.

class TheHostProgram
{
    static void Main(string[] args)
    {
        var instance = new TodoResource(new ToDoMemoryRepository());
        using (var host = new HttpServiceHost(instance, "http://localhost:8080/todo"))
        {
            host.Open();
            ShowEndpointsOf(host);
            WaitForKey();
        }
    }

    private static void ShowEndpointsOf(ServiceHost host)
    {
        Console.WriteLine("Host is opened with the following endpoints:");
        foreach (var ep in host.Description.Endpoints)
        {
            Console.WriteLine("\tEndpoint: address = {0}; binding = {1}", ep.Address, ep.Binding);
        }
    }

    private static void WaitForKey()
    {
        Console.WriteLine("Press any key to stop host...");
        Console.ReadKey();
    }
}

That’s it.

Notice:

  • The ShowEndpoints and WaitForKey methods are just utility functions to show the opened endpoints and wait for user input.
  • The use of a new service host type – HttpServiceHost.
  • For simplicity, the service uses InstanceContextMode.Single. This means that I can pass the resource class instance directly to the service host. This allows me to resolve its dependencies (the IToDoRepository) manually. In a future post, I will show how to use an IoC/DI container to obtain the resource class instances.
  • No endpoint has to be explicitly added. The HttpServiceHost automatically adds an endpoint for each defined base address defined in the constructor.
  • This default endpoint will have the “http://localhost:8080/todo” base address. Note that the URI templates defined in the resource class are relative to this base address. For instance, a GET request to “http://localhost:8080/todo/123” will be associated with the GetToDo operation (“{id}” template). The template’s id variable will be bound to “123”.

Explicit endpoints can also be added using the old AddServiceEndpoint method, before the service is opened:

host.AddServiceEndpoint(typeof(TodoResource), new HttpBinding(), "http://localhost:8080/todo2");

The host will not add default endpoints if there are explicit endpoints added.

When explicitly adding an endpoint, notice  the usage of a new binding – HttpBinding. This is the binding also used in the default endpoints.

Currently, it is even possible to use the old ServiceHost to host a resource class. However, the new HttpBehavior behavior must be added to each endpoint.

var repository = new ToDoMemoryRepository();
repository.Add(new ToDo("Must learn HTTP better"));
var instance = new TodoResource(repository);
using (var host = new ServiceHost(instance))
{
    var ep = host.AddServiceEndpoint(typeof(TodoResource), new HttpBinding(), "http://localhost:8080/todo2");
    ep.Behaviors.Add(new HttpBehavior());
    host.Open();
    ShowEndpointsOf(host);
    WaitForKey();
}

It is this HttpBehavior and the HttpBinding that “insert” the new WCF Web API model into the WCF runtime. When using HttpServiceHost, this behavior is automatically added.

Tagged with: ,

WCF Web API–Elementary programming model

Posted in Software by pedrofelix on April 19, 2011

This is the first post on a series about the new Preview 4 of WCF Web API. In this post, I will start presenting the elementary aspects of the programming model.

Service classes/Resource classes and operations

It all starts with a class annotated with the ServiceContractAttribute attribute, usually called the resource class. In the WCF Web API, this class is just a container for methods that will handle HTTP requests for a set of related URIs. In WCF terminology, these methods are called operations.

As an example, consider the management of a “to do” list. A resource class for such scenario will typically contain methods/operations to handle the following HTTP methods:

  • GET the “to do” list;
  • POST a new “to do” into the list;
  • GET a specific “to do”;
  • DELETE a specific “to do”;
  • PUT an update to an existing “to do”.

This results in the following class.

    [ServiceContract]
    class TodoResource
    {
        [WebGet(UriTemplate = "")]
        HttpResponseMessage GetAllToDos(){...}

        [WebInvoke(UriTemplate = "", Method = "POST")]
        HttpResponseMessage PostNewTodo(HttpRequestMessage req){...}

        [WebGet(UriTemplate = "{id}")]
        HttpResponseMessage GetToDo(int id){...}
        
        [WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
        HttpResponseMessage DeleteToDo(int id){...}
        
        [WebInvoke(UriTemplate = "{id}", Method = "PUT")]
        HttpResponseMessage UpdateToDo(int id, HttpRequestMessage req){...}        
    }

Association between HTTP requests and Operations

The association between an HTTP request and the operation  that will handle it is done via the WebGetAttribute and WebInvokeAttribute attributes. Notice how each method in the above class is annotated with one of these attributes.

The association uses two properties of a HTTP request:

  • The request URI;
  • The request method (e.g. GET, POST)

The WebGetAttribute associates the annotated method to requests with GET method and an URI that matches the WebGetAttribute .UriTemplate property.

The WebInvokeAttribute associates the annotated method to requests with a HTTP method contained in the WebInvokeAttribute.Method property, and an URI that matches the WebGetAttribute.UriTemplate property.

Operation Parameters

A resource class doesn’t have to derive from any class or interface. This means that there isn’t any language contract that an operation method must implement. Namely:

  • Operation methods can have any name;
  • The parameters and return type of an operation method are not defined by a base class or interface.

Instead, we can see the operation parameters as dependencies that WCF will try to resolve during runtime, using information derived from the request. In future posts, I will describe how this resolution is performed and how it can be extended.

Similarly, there isn’t any language contract specifying the return type of an operation. Instead, the WCF runtime will try to use the operation’s return value to build a HTTP response.

This absence of language contracts means that errors are not caught at compile time. Instead, if the operation parameters cannot be resolved, an error will occur only at service startup.

The HttpResponseMessage class

One of the return types allowed for an operation is the HttpResponseMessage type, which is a strongly typed representation of an HTTP response.

For instance, the GetAllToDos operation,  which handles a GET over the “to do” collection, uses it to completely control the response.

[WebGet(UriTemplate = "")]
HttpResponseMessage GetAllToDos()
{
    return new HttpResponseMessage()
    {
        StatusCode = HttpStatusCode.OK,
        Content = new StringContent(
            String.Concat(_repository.All.Select(t => t.ToString())))
    };
}                  

Notice the following:

  • The StatusCode property is of of type HttpStatusCode, which is an enum containing all the standard status codes.
  • The response body is controlled via the Content response property. In this case, a string type content is used (StringContent class), which results in a “text/plain” media type.

The HttpRequestMessage class

One of the accepted operation parameter types is the HttpRequestMessage, which is a strongly typed representation of a HTTP request.

For instance, the PostNewToDo operation uses this type as a parameter to obtain the “to do” representation from the request body

[WebInvoke(UriTemplate = "", Method = "POST")]
HttpResponseMessage PostNewToDo(HttpRequestMessage req)
{
    var body = req.Content.ReadAsString();
    dynamic formContent = FormUrlEncodedExtensions.ParseFormUrlEncoded(body);
    string description = formContent.Description;
    if (description == null)
    {
        return new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.BadRequest
            };
    }
    var td = new ToDo(description);
    _repository.Add(td);
    var response = new HttpResponseMessage();
    response.StatusCode = HttpStatusCode.Created;
    string uriString = req.RequestUri.AbsoluteUri + "/" + td.Id.ToString();
    Uri uri = new Uri(uriString);
    response.Headers.Location = uri;
    response.Content = new StringContent(uri.AbsoluteUri, Encoding.UTF8, "text/uri-list");
    return response;
}

Notice:

  • The parsing of the request into a dynamic object;
  • If the body does not contain a “description”, then a “Bad Request” response is returned;
  • If the new “to do” is successfully created, then a “Created” response is returned with a “Location” header containing this new “to do” URI.

UriTemplate variables

An operation can also have parameters whose names equals an URI template variable. For instance, the GetToDo operation uses this feature to obtain the “to do” identifier.

[WebGet(UriTemplate = "{id}")]
HttpResponseMessage GetToDo(int id)
{
    ToDo td = _repository.All.Where(t => t.Id == id).FirstOrDefault();
    if (td == null)
    {
        return new HttpResponseMessage()
        {
            StatusCode = HttpStatusCode.NotFound
        };
    }
    return new HttpResponseMessage()
    {
        StatusCode = HttpStatusCode.OK,
        Content = new StringContent(td.ToString())
    };
}

Notice:

  • The id parameter, that will be bound to the id variable on the “{id}” URI template.

The HTTP protocol as a first class concept

The initial version of WCF was heavily based on the SOAP model, where HTTP is just one of the available mechanisms to transport SOAP messages. The transport independence of the SOAP model means that the transport mechanisms are, for the most part, abstracted away behind a binding. 

However, WCF Web API aims to provide a “first class experience” for using HTTP. This means exposing HTTP as a transfer protocol in its full glory and not hiding it.

The use of the HttpRequestMessage and HttpResponseMessage types, as parameter and return type of the operations, are a way of giving direct access to the HTTP protocol, without some of the parsing and encoding complexity.

Notice also that the HTTP request information is explicitly passed into an operation as an HttpRequestMessage and not obtained from the “current context" (e.g. WebOperationContext.Current on previous versions of WCF).

The HttpRequestMessage and HttpResponseMessage classes belong to the Microsoft.Net.Http and are not dependent on WCF. Namely, these classes can be easily instantiated without having to use any WCF artifact.

These two aspects are essential for the operation testability, as we shall see in future posts.

The full code for this example can be found at github.

In the next post, I will describe how to host this service class/resource class.

Tagged with: ,

WCF Web API–Preview 4

Posted in Software by pedrofelix on April 19, 2011

At PDC 2010, Glenn Block announced a new WCF based library for building Web based Application Programming Interfaces (API) – the WCF Web API. One of it goals is to provide a “first class experience” for using  HTTP. The first preview of this library, including source code, was published at http://wcf.codeplex.com.

This week, at MIX 11, the WCF Web API Preview 4 was finally published, providing a more matured programming model and implementation. The source code is also available on a Mercurial repository. To clone it, just do hg clone https://hg01.codeplex.com/wcf.

In the next posts, I will present an overview of this new WCF library.

Note: Preview 5 was released on September, 2011. The next posts and demos are based on this new release.
Tagged with: ,
Follow

Get every new post delivered to your Inbox.