Showing posts with label ASP.NET MVC 4.0 beta. Show all posts
Showing posts with label ASP.NET MVC 4.0 beta. Show all posts

Monday, 28 May 2012

ASP.NET Web API Series - Part 7: Real world Message Handlers


Introduction

[Level T2] In the previous post we reviewed Web API's pipeline a.ka. Russian Doll model. In this post we further on what discussed with a few examples built by the community. Also before that, we look on how to use a per-route message handler while keeping all the goodness of controller functionality.

If you have written a real-world handler in ASP.NET Web API, please contact me in the comments below or on Twitter (@aliostad) to be reviewed and added to the post.

Have the cake and eat it at the same time

In the previous post, we talked about the benefits of the per-route message handlers. Henrik's example is an implementation of HttpMessageHandler which will basically needs to do every thing by itself. So the question arises, how can I have the flexibility of the per-route message handlers while benefit from all the luxury of formatting, action invocation, controller mechanisms, etc. In other words, how can I invoke my controller in a per-route case? Well that sounds like have the cake and eat it at the same time.


Well, it turns out it is possible. I managed to get this working, calling my actions using a per-route handler. The trick is that you set up your Russian dolls and last one ending with an HttpControllerDispatcher.

So let's look at an example. Here we have is a humble delegating handler that outputs the request URL to the trace.

public class TraceHandler: DelegatingHandler
{
 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
 {
  Trace.WriteLine(request.RequestUri.ToString());
  return base.SendAsync(request, cancellationToken);
 }
}

Now if we want to set up this DelegatingHandler per-route, we simply create a new HttpControllerDispatcher and set it to the InnerHandler of the TraceHandler:

config.Routes.MapHttpRoute(
 "DefaultApi",
 "api/{controller}/{id}",
 new{ id = RouteParameter.Optional},
 null,
 new TraceHandler(){InnerHandler = new HttpControllerDispatcher(config)});

Creating HttpControllerDispatcher is easy and we just need to pass the HttpConfiguration object (depending on the SelfHost or Web scenario).

So this way we can have our per-route delegating handler running only for that route yet all the controller action binding and formatting intact.

Real-world message handlers

Since the beta version of the Web API was out, community has been building interesting and useful handlers. So I thought instead of me coming up with arbitrary or simple cases, I could introduce the great stuff community has done so far. And that is what I did. The very last one is the introduction of my CachingHandler which deserves a post on its own.

Tracking Web API usage by your customers

Filip Woj shows us how to build a DelegatingHandler to support tracking usage of your API. But not just that, actually all the nitty-gritty of building the infrastructure (repositories, etc) to support it. This can be a very useful feature if you want to monetise your API and need to charge per call or make sure the call is made within the number of calls allowed for the customer.

Radenko tries to solve a similar problem with throttling usage of the API. He uses HttpRuntime.Cache for storing the statistics. As he explains, he will be moving the storage to Membase. Generally use of the cache for storing data is not great since system can remove the data if memory becomes a scarce resource (which happens often on a web server, especially the one needing throttling).

Authentication and security

John Petersen looks into using a delegating handler for token-based authentication. He uses public/private key and RSA for creating tokens (perhaps we could also choose a stronger algorithm since token is small unlike the whole HTTP communication) and creates 3 different handlers: one to make sure the request uses TLS/SSL, other to ensure the IP address of the client is from a white-list and finally the handler to create and verify authentication token.

Antony Scott also takes on the Basic Authentication and explains how to process the authentication header and set the identity of the current thread. There is not a lot of code there, not more than you need displaying how easy it is to do basic authentication if you use all the correct points of the system.

Perhaps the most important implementation of security which also includes use of message handlers, is Dominick Baier's Thinktecture Identity model on github. Dominick explains this in his blog post here and his library supports all major standards.

Other

Mike Wasson explains here how to create HTTP method override delegate in ASP.NET Web API. The idea is that using HTTP methods other that POST and GET might be tricky on some servers. For example, there is a known issue in IIS whereby PUT or DELETE methods will return 404 if you have WebDAV installed on the server. In such cases, by convention client sends a custom HTTP header with the key of X-HTTP-Method-Override containing the alternate method. In this case, the handler will read the header and change the method. It is important to note that binding to the controller and action selection and invocation happens later so this change of method will be effective. 

Caching

HTTP caching is a very important feature in RFC 2616. A whole chapter in the spec is dedicated to it and arguably involves some of the most complex rules in the whole spec. Caching is also one of the tenants of REST and as such plays an important role in the design, architecture and scalability model of the web. In the last few weeks I have been busy building a CachingHandler for the WebApiContrib and currently it is available in my fork of the project. In the next post, I will be going through some of the challenges I was facing and the solutions I came up in writing this complex handler. It was good fun!

Conclusion

Per-route message handlers can be enhanced if we mix delegating handler(s) with HttpControllerDispatcher. In this case, we can have a number of delegating handlers last one ending with the controller dispatcher. This leaves media formatting, controller selection, model binding and action invocation intact while we can have all the flexibility of per-route handlers.

We also reviewed a few useful handlers built by the community and available at the time of writing this post. In the next post, we will cover the CachingHandler.

Saturday, 19 May 2012

ASP.NET Web API Series - Part 6: MessageHandler explained


Introduction

[Level T3] MessageHandler is a new concept in ASP.NET Web API and a very useful tool in separation of concerns in a Web API service. In this article we will review the concept and outline its usefulness with a few simple examples.

Background

IIS as the Windows platform's HTTP server implementation, has always had two concepts: a component that receives HTTP request and responsible for returning a response (endpoint of communication), and another component that sniffs the communication and can quietly read/write from/to the request/response.

In the old times of unmanaged C++ IIS application implementation, we had ISAPI extensions and ISAPI filters. So the first one was responsible for reading request and sending back a response while the other, would be sniffing incoming and outgoing messages and perhaps sneak in/out a few headers or content. Difference also explained here.

In ASP.NET we had the same two familar concepts: HTTP Handlers and HTTP Modules with corresponding IHttpHandler and IHttpModule interfaces, respecitvely. Again here, we had handlers responsible for handling the request and returning a response, while HttpModule would be sitting as a not-so-innocent-bystander and sniff in what goes and chip in when necessary.

To illustrate this further, all Web Forms pages or MVC controllers can be looked as HTTP Handlers (although the interface itself would be implemented much higher in the pipeline but would delegate the responsibility to page or controller action). On the other hand, useful tools such as Glimpse or ELMAH use HTTP module to intercept the errors or routes from the stream of incoming/outgoing request/response. ASP.NET MVC has a concept of ActionFilter which is similar but for the sake of brevity it is better not to delve into it.

ASP.NET Web API continues these two concepts yet combines them into HttpMessageHandler which is the base class for important classes in the stack such as HttpServer, HttpControllerDispatcher and HttpRoutingDispatcher. This class can be implemented as both an equivalent of HTTP module or handler. Yet DelegatingHandler, a subclass of HttpMessageHandler has been specialised into an equivalent of HTTP module. While understanding of HttpMessageHandler is important, it is much more likely that you will only implement DelegatingHandler. As such we cover it in more details.

DelegaingHandler in Web API

DelegatingHandlers are used in the Web API to represent Message Handlers before routing (see below). They are ordered modules in the HTTP pipeline stream each one receiving request, doing some work and pass to the next. On the outbound stream also response is taken, processed passed to the next. However, at any point, a handler can decide to take action and process the request returning the response without passing to the next one. If I need to show this, I would use my very crude drawing techniques:

Request/Response pipeline and Message Handlers in ASP.NET Web API - in a crude way :)


So now let's think about it. We have a stack of message handlers: first handler to receive the request is the last one to be passed the response, vice versa. This is similar to Russian Dolls, each inside the other.

Russian doll model

If you have not seen Russian dolls, well there it is for you:



 The idea is that you you buy just the biggest doll and once you open it, you find a smaller one and if you open that one, you see a smaller... until you get to the last one. 

So let's look at the DelegatingHandler and other classes in the hierarchy:

Class hierarchy of Message Handlers in System.Net.Http.dll

As can be seen, DelegatingHandler is a derived class from HttpMessageHandler and has a property of InnderHandlerThis inner handler in fact is the smaller Russian Doll inside the handler. So as you can imagine all these handlers are chained together using this InnerHandler property.

There is in fact some code in ASP.NET Web API that turns IEnumerable<DelegatingHandler> into a chain of DelegatingHandlers.

How does a DelegatingHandler work?

DelegatingHandler mainly has to implement SendAsync method. This method receives a HttpRequestMessage (and a cancellation token) and must return a Task<HttpResponseMessage>. So you might have expected to see two methods, one for handling request and one for handling response, but they are all combined into one because of the power and beauty of Task<T>.

Basically in a delegating handler, if you need to inspect the request then you would simply do it in the SendAsync. However, if you need to work on the response, you would do it in the continuation of the Task.

So let's see some code. Let's imagine I need to write to the trace all incoming request URLs and add a custom response header identifying that this URL has been written to the trace (a very fictitious case, we will see some real world scenarios in the next post), we can code it very easily:


public class DummyHandler : DelegatingHandler
{
 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
 {
  // work on the request 
  Trace.WriteLine(request.RequestUri.ToString());

  return base.SendAsync(request, cancellationToken)
   .ContinueWith(task =>
                {
      // work on the response
                   var response = task.Result;
        response.Headers.Add("X-Dummy-Header", Guid.NewGuid().ToString());
        return response;
                });
 }
}


Execution of message handlers in Web API pipeline

Until recently, you could only register MessageHandlers globally. ASP.NET team have recently added much awaited per-route message handler support announced only a few weeks ago.

So as explained and illustrated by Henrik in the link above (and also by Kiran Challa in his nice diagram), execution of message handlers depends on whether they are registered globally or per-route. Global message handlers are executed before HttpRoutingDispatcher work while per-route message handlers are executed after it.

Registering a global message handler (DelegatingHandler)

Global message handlers (must be DelegatingHandlers) are a property of the configuration object. In a web hosted Web API:

GlobalConfiguration.Configuration.MessageHandlers.Add(
    new DummyHandler());

As we discussed, the order of registering a handler is very important and defines the size of the Russian doll, higher it is in the list, more powerful it will be as it becomes the soonest receiving the request and last receiving the response (hence more flexibility and breadth of operation).

UPDATE 06/08/2012:  The order of calling message handlers has changed for RTM release. So in RTM, first item is called first for request and last for response.

Registering a per-route message handler(s)

This is easy and is at the same time of registering the route itself. Here we register MyMessageHandler:

IHttpRoute route = config.Routes.CreateRoute(
 routeTemplate: "api/MyRoute",
 defaults: new HttpRouteValueDictionary("route"),
 constraints: null,
 dataTokens: null,
 parameters: null,
 handler: new MyMessageHandler());

config.Routes.Add("MyRoute", route);

One might wonder, it would have been great if we could register a collection of delegating handlers along with the actual handler. In fact we can! Se let's say we have two DelegatingHandler implementations as RussianDoll_1 and RussianDoll_2. So we can now say:

var handler = new RussianDoll_1()
 {
  InnerHandler = 
   new RussianDoll_2()
   {
    InnerHandler = new MyMessageHandler()
   }
 };

IHttpRoute route = config.Routes.CreateRoute(
 routeTemplate: "api/MyRoute",
 defaults: new HttpRouteValueDictionary("route"),
 constraints: null,
 dataTokens: null,
 parameters: null,
 handler: handler);

config.Routes.Add("MyRoute", route);

Conclusion

In this post, we briefly reviewed the history of two types of HTTP pipeline components: the one that is responsible for processing a request and sending back a response, and the other, a mid-stream component in the HTTP pipeline sniffing the incoming and outgoing request/response which can sometimes intervene in the message processing.

In brief, Web API heavily uses the abstraction of HttpMessageHandler and DelegatingHandler - latter inheriting from the former. Web API allows for registration of global message handlers or per route handlers. In the next post, we will review some of the real-world use cases of Message Handlers.

Saturday, 28 April 2012

ASP.NET Web API Series - Part 5: MediaTypeFormatter explained


Introduction

[Level T2] MediaTypeFormatter is an exciting concept introduced in the ASP.NET Web API which will enable seamless conversion of HTTP data to/from.NET types. This post reviews the concepts and basic usage of MediaTypeFormatter in the ASP.NET Web API pipeline. This is an area of Web API which is being actively developed so the content of this post might be updated to reflect the changes - but this post at the time of publishing is based on the latest source code available.

Background

HTTP abstracts a resource (identified by a URI which is commonly a URL) from its representation. A resource e.g. an employee detail can be identified by /employees/123. An HTTP agent (client) and a server engage in content negotiation to decide on the best format it can be represented. For example, a client can express its wishes to receive employee detail in plain text (by specifying content-type header of text/plain), RTF, XML, JSON or even image.

On the other hand, ASP.NET Web API has also abstracted away parameters or result of an action form its representation. While ASP.NET MVC had this feature for input parameters, return type should have been an instance of ActionResult hence controller had to make a decision on the format of resource by returning ContentResult, JsonResult, etc.

MediaTypeFormatter as we will see will bridge the gap between these two abstractions.

What is Media Type?

As you all probably know, media type refers to the value of the content-type header within an HTTP request and response. Media types allow agent (client) and server to define the type of the data sent in the HTTP body (payload). It is also used within the accept header in the request to allow content negotiation, i.e. client notifies the server of the media types it accepts/prefers. I will need to have a separate post on content negotiation but as for now, this little introduction suffices.

There are standard media types as listed in the Wiki link. There is no limitation on the media types and you can come up with your own media types but these media types usually start with X-.

A request or response does not have to have a single media type. It can mix the media types but in this case it has to use multipart content-type (value of the content type will be multipart/mixed) so that each part defines its content type.

What is MediaTypeFormatter?

Media type formatter is the bridge between the HTTP world of URI fragments, headers and body on one side, and the controller world of actions, parameters and return types.

Tower Bridge of Web API
Tower Bridge of ASP.NET Web API

A media type formatter in brief:
  1. Has a knowledge of one or more media type (for example text/xml and application/xml both refer to the same structure which is XML) and tells Web API which content types it supports (for the HTTP world)
  2. Tells Web API whether it can read or write a type (for Controller world)
  3. Has an understanding of encoding/charset which is passed in the HTTP header and can read accordingly
  4. It will be given a stream to read (from request) or write (to response)
  5. Its work usually (but not always) involves serialisation (at the time writing to the response) or deserialisation (at the time of reading from the request)
  6. Inherits abstract class MediaTypeFormatter

MediaTypeFormatter class

MediaTypeFormatter class in the ASP.NET Web API is an abstract class providing base services for various media type formatters.

Important properties and methods include (more informative as code):

public abstract class MediaTypeFormatter
{

 // properties
 public Collection<MediaTypeHeaderValue> SupportedMediaTypes { get; private set; }
 
 public Collection<Encoding> SupportedEncodings { get; private set; }
 
 public Collection<MediaTypeMapping> MediaTypeMappings { get; private set; }
 
 // methods
 public virtual Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger)
 {
  // to be overriden by base class
 }

 public virtual Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, TransportContext transportContext)
 {
  // to be overriden by base class
  }

 public abstract bool CanReadType(Type type);

 public abstract bool CanWriteType(Type type);

}


Things to note above are:

  • As with the rest of the Web API, MediaTypeFormatter fully supports Async using TPL. Having said that, most implementations of  MediaTypeFormatter run synchronously as they involve serialisation which is safe as a synchronous operation. 
  • SupportedMediaTypes defines a list of media type headers that an implementation supports. For example application/xml and text/xml
  • MediaTypeMappings is an interesting concept where a media type formatter can define its preference for a particular media type based on a value in the request (query string, URI fragment, HTTP header). A typical example is existence of x-requested-with header which signals the AJAX based request hence JSON is the preferred content-type.

How ASP.NET Web API uses formatters?

Media type formatters are global formatters sitting in the Formatters property of HttpConfiguration. If you are using ASP.NET hosting (IIS, Cassini, etc) then you may use GlobalConfiguration.Configuration to access the instance of HttpConfiguration containing Formatters. If you are using Self-Hosting, then you would be creating a HttpSelfHostConfiguration object which you will use its Formatters property.

This snippet will output all formatters that are setup by default in the ASP.NET Web API:

foreach (var formatter in config.Formatters)
{
 Trace.WriteLine(string.Format("{0}: {1}", 
  formatter.GetType().Name,
  string.Join(", ", formatter.SupportedMediaTypes.Select(x=>x.MediaType))
  ));
}

And here is the output (at the time of writing this blog):

JsonMediaTypeFormatter: application/json, text/json
XmlMediaTypeFormatter: application/xml, text/xml
FormUrlEncodedMediaTypeFormatter: application/x-www-form-urlencoded
JQueryMvcFormUrlEncodedFormatter: application/x-www-form-urlencoded
This list is very much likely to be extended by the time ASP.NET Web API is shipped. 

You might be surprised to see two different media type formatters targeting the same media type. But that is very normal: media type formatters compete for becoming the formatter of choice! If ASP.NET Web API find two formatters for the same content type, it will pick the first one so it is very important to add formatters in the right order.

Writing a simple BinaryMediaTypeFormatter

Now, we want to get our hands dirty and implement a useful formatter that is not currently provided by the ASP.NET Web API. This formatter will be able to formatter application/octet-stream media type in the HTTP world to the byte[] type in the controller world.

Let's imagine we have a controller that calculates SHA1 hash of the small binary data posted to it (this is a good practice for large streams):

public class BinaryController : ApiController
{
 [HttpPost]
 public string CalculateHash(byte[] data)
 {
  using(var sha1 = new SHA1CryptoServiceProvider())
  {
   return Convert.ToBase64String(sha1.ComputeHash(data));       
  }
 }
}

In our implementation, we use synchronous approach, although in this case it is safe to use asynchronous as there is no serialisation taking place. However, since this is intended only for small payloads, context switching of the asynchronous TPL has more overhead - in any case turning this code into asynchronous is very easy: an alternate implementation supporting async can be found here.


public class BinaryMediaTypeFormatter : MediaTypeFormatter
{

 private static Type _supportedType = typeof (byte[]);
 private const int BufferSize = 8192; // 8K 

 public BinaryMediaTypeFormatter()
 {
  SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
 }

 public override bool CanReadType(Type type)
 {
  return type == _supportedType;
 }

 public override bool CanWriteType(Type type)
 {
  return type == _supportedType;
 }

 public override Task<object> ReadFromStreamAsync(Type type, Stream stream, 
  HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger)
 {
  var taskSource = new TaskCompletionSource<object>();
  try
  {
   var ms = new MemoryStream();
   stream.CopyTo(ms, BufferSize);
   taskSource.SetResult(ms.ToArray());
  }
  catch (Exception e)
  {
   taskSource.SetException(e);
  }
  return taskSource.Task;
 }

 public override Task WriteToStreamAsync(Type type, object value, Stream stream, 
  HttpContentHeaders contentHeaders, TransportContext transportContext)
 {
  var taskSource = new TaskCompletionSource<object>();
  try
  {
   if (value == null)
    value = new byte[0];
   var ms = new MemoryStream((byte[]) value);
   ms.CopyTo(stream);
   taskSource.SetResult(null);
  }
  catch (Exception e)
  {
   taskSource.SetException(e);
  }
  return taskSource.Task;
 }
}

Using BinaryMediaTypeFormatter

Now let's use our formatter. You need a REST console of your choice (Chrome REST console, REST Sharp library, Fiddler) to send this request:

POST http://localhost:7777/api/Binary HTTP/1.1
User-Agent: Fiddler
Host: localhost:7777
content-type: application/octet-stream
Content-Length: 14

This is a test

Since we have not yet added our formatter, we get back this error:
No MediaTypeFormatter is available to read an object of type 'Byte[]' from content with media type 'application/octet-stream'.
So we just need to add our formatter:

config.Formatters.Add(new BinaryMediaTypeFormatter());

And we will get back this response:

HTTP/1.1 200 OK
Content-Length: 30
Content-Type: application/json; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
Date: Sat, 28 Apr 2012 12:09:44 GMT

"pU2I4GYS2CC8O+cod8dPJXtWGxk="
As you can see, the response content type is application/json. I have explained in my post Part 1 why it is the case: JsonMediaTypeFormatter is the default media type formatter. Now we know why it is the case: it is the first item in the collection (see above).

Conclusion

Media type formatter is the bridge between the HTTP world of URI, headers and body on one side, and the controller world of actions, parameters and return types. In ASP.NET Web API, it is represented by abstract class MediaTypeFormatter. Order of formatters in the Formatters property of HttpConfiguration is important when ASP.NET Web API has to choose between two formatters supporting the same media type.

Sunday, 15 April 2012

ASP.NET Web API Series - Part 3: Async Deep Dive

[Level T4]

OK, in this post we will have a look at the internals of ASP.NET Web API and its async implementation. [For a newer related post see here]

As covered some ground in our previous post, we will continue our journey while this time we will have a look at the async used in the Web API Source Code was that was released recently. For more information about building and using the source code, please see my earlier post.

First some myth-busting and de-mystifying.

What exactly is Task<T>

If you start browsing through the source code of the ASP.NET Web API, you will find very few classes where they do not have xxxAsync() method or do not contain methods returning varieties of Task<T> (which from here on, I am gonna use to generically refer to all tasks including all variations such as Task and Task<T>).

Task allows the operations to be scheduled asynchronously, however, the question is now that most methods return Task<T>, would the context switching of all these asynchronous operations not have an adverse effect on the performance of the Web API? At the end of the day, async was added to improve the scalability but can adversely damage the performance? As we will see below, ASP.NET Web API runs actions asynchronously only if you tell it to - hence no context-switching happens within the framework for non-Task actions. And for Task actions, since we are dealing with long running processes, asynchronous processing provides scalability.

And here is the myth-busting:
TASK       ASYNC 
While Task<T> was designed and built to serve as an easy, approachable and consistent asynchronous programming model, it does not necessarily mean a Task<T> will run on a background thread or in the ThreadPool. In fact, this is very much the case for xxxAsync methods in the framework, as we will see shortly.

Have a look at the code below:

Thread.CurrentThread.Name = "Main Thread";
Func<string> f = () =>
 {
  Console.WriteLine(Thread.CurrentThread.Name);
  return "Ali";
 };
Task<string> t = new Task<string>(f);
t.RunSynchronously();
Console.WriteLine(t.Result);
// OUTPUT:
// Main Thread
// Ali


So as it can be seen above RunSynchronously will run the task in the current thread - hence the thread names are the same.

So what is Task then? I would like to describe Task as below:
Task is nothing but a wrapper class that encapsulates a delegate and its state (result, status, exception, etc)
In fact, it is the Scheduler (which can be passed as an argument to Start) which defines how the task should run. Default scheduler (when constructing the task without passing scheduler or using Task.Factory.StartNew()) runs the task in the ThreadPool. This is different from the original scheduler initially designed that used to have a dedicated scheduler with as many threads as CPUs on the box (see here for discussion on the subject).


Web API Pipeline

This subject deserves its own post which I will get to but in the meantime, let's look at the processing pipeline from the moment request is received by the server until action is called on the controller. 

This is an simplified view of the pipeline (which for now serves our purpose):


In terms of servers, currently there are two out-of-the box server scenarios in Web API:
  • ASP.NET Pipeline: this involves using IIS, IIS Express or Visual Studio Development Web Server (Cassini)
  • Self hosting
In terms of Self Hosting, HttpSelfHostServer receives the request and process it using 
ProcessRequestContext which passes a ChannelContext and RequestContext. This is reminiscent of good old ISAPI entry pointHttpSelfHostServer will call its base class's (HttpServer) SendAsync which is the first place we see the Task<T>:
protected override Task<HttpResponseMessage> 
    SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

This method is responsible for copying some context to the Thread Storage Area and HTTP request properties. But the returned task is not created in this method and is returned from its base class DelegatingHandler. This class does nothing but to call SendAsync on its inner handler (i.e. it delegates the call to another handler). This object is one of the classes inherited from HttpMessageHandler (in fact DelegatingHandler itself is such a derived class). In a typical Web API scenario, this class is HttpControllerDispatcher.

Dispatchers are responsible for finding the actual handler (in our case the controller) and preparing the state for its execution and final release of the handler. In this case, HttpControllerDispatcher does exactly that. But it is important that dispatcher here only returns the Task<HttpResponseMessage> returned to it by the controller, so again does not create the task.

Controllers are the ones doing the actual work hence the method name changes from SendAsync to ExecuteAsync. The bulk of the work is done in the ApiController. This class gathers controllerDescriptor, actionDescriptor and filters and in essence, returns HttpActionInvoker's InvokeActionAsync. Note that SendAsync changed to ExecuteAsync and now it is InvokeActionAsync.

We have not yet seen the creation of the task! But we are not too far off. Most of the heavy lifting is done in the private class ActionExecuter of ReflectedHttpActionDescriptor. This class compiles a lambda expression based on the return type of the action:
if (methodCall.Type == typeof(Task))
{
 // for: public Task Action()
 return ...
}
else if (typeof(Task).IsAssignableFrom(methodCall.Type))
{
 // for: public Task<T> Action()
 return ...
}
else
{
 // for: public T Action()
 return ...
}

If the return type is Task, or Task<T>, it will return the task. But what if it is a non-Task return type? Well, it executes the action to get the result and wraps it in a task:
var result = compiled(instance, methodParameters);
...
return TaskHelpers.FromResult(result);
TaskHelpers.FromResult simply creates a dummy task and sets the result.

How much of the Web API runs asynchronously?

Almost zero if you do not return Task or Task<T>! In order to investigate this, we will use a simple technique to trace the thread switching from the time request is picked up by the server (in this case Self-Host) all the way to the controller and then back again.

I use this simple code to name the current thread to the "class.method()" name if it already does not have a name - I also use a prefix for ability to filter these debug outputs from the rest. Remember that assigning a name to a thread already having a name throws exception. We also output the name using Trace.WriteLine():
using System.Diagnostics;

namespace System.Threading
{
 public static class ThreadNameTracingExtensions
 {
  /// <summary>
  /// if thread has a name, it leaves the name as it is. If it does not have a name,
  /// it sets the thread's name to the module.method
  /// It outputs as 
  /// </summary>
  /// <param name="thread"></param>
  public static void TraceName(this Thread thread)
  {
   var st = new StackTrace(new StackFrame(1));
   var methodBase = st.GetFrame(0).GetMethod();
   string name = string.Format("{0}.{1}()", methodBase.ReflectedType.Name, methodBase.Name);
   Trace.WriteLine(string.Format("__ThreadName__ => {0}: '{1}'", name, thread.Name));
   if (string.IsNullOrEmpty(thread.Name))
    thread.Name = name;
  }
 }
}

And now we just sprinkle this line of code in various points in the pipeline:
System.Threading.Thread.CurrentThread.TraceName();

Let's look at how this will behave for an action returning a string:
[HttpGet]
public string Test(int id)
{
 System.Threading.Thread.CurrentThread.TraceName();
 return "Test";
}

Here is the trace output (I have removed "__ThreadName__ => " prefix):


HttpServer.Initialize(): ''
HttpControllerDispatcher.SendAsync(): 'HttpServer.Initialize()'
ApiController.ExecuteAsync(): 'HttpServer.Initialize()'
<>c__DisplayClass3.<ExecuteAsync>b__0(): 'HttpServer.Initialize()'
ApiControllerActionInvoker.InvokeActionAsync(): 'HttpServer.Initialize()'
<>c__DisplayClass3.<InvokeActionAsync>b__0(): 'HttpServer.Initialize()'
ReflectedHttpActionDescriptor.ExecuteAsync(): 'HttpServer.Initialize()'
<>c__DisplayClass5.<ExecuteAsync>b__4(): 'HttpServer.Initialize()'
HelloWorldController.Test(): 'HttpServer.Initialize()'
So as you can see from above, the thread that initialised HttpServer, will call all the methods in the pipeline, including all those xxxAsync methods. Our action is also called synchronously by the same thread. Note anonymous methods created by lambda style delegate definitions all the way through the pipeline.

It seems to me that ASP.NET team have decided to add Async suffix to all methods that could be called asynchronously rather than would be called asynchronously. I would like to get a confirmation if it is the case or I am missing something since I am for now using Self-Hosting. In any case, I think this naming could be misleading and perhaps is a misnomer (although alternative ExecuteCanBeAsync is ugly!) but I trust the team had a good reason to use this name.


Now let's look at an action that returns a task: 

[HttpGet]
public Task<string> AsyncCall()
{
 System.Threading.Thread.CurrentThread.TraceName();
 var task =
  new Task<string>(
   () =>
   {
     
     System.Threading.Thread.CurrentThread.TraceName();
     Thread.Sleep(20 * 1000); // 20 seconds
     System.Threading.Thread.CurrentThread.TraceName();
     return "AsyncCall";
   }
  );
 task.Start();
 return task;
}

And here is the output:

ApiController.ExecuteAsync(): 'HttpServer.Initialize()'
<>c__DisplayClass3.<ExecuteAsync>b__0(): 'HttpServer.Initialize()'
ApiControllerActionInvoker.InvokeActionAsync(): 'HttpServer.Initialize()'
<>c__DisplayClass3.<InvokeActionAsync>b__0(): 'HttpServer.Initialize()'
ReflectedHttpActionDescriptor.ExecuteAsync(): 'HttpServer.Initialize()'
<>c__DisplayClass5.<ExecuteAsync>b__4(): 'HttpServer.Initialize()'
HelloWorldController.AsyncCall(): 'HttpServer.Initialize()'
HelloWorldController.<AsyncCall>b__0(): ''
HelloWorldController.<AsyncCall>b__0(): 'HelloWorldController.<AsyncCall>b__0()'
So as we can see, the initial thread runs the code including the action. However since we are doing the actual work in an action, action is called in a background (ThreadPool) thread - note the last two lines. 


So as we have seen, unless you return a Task or Task<T>, all the pipeline runs synchronously.

Synchronisation

OK, with task-based operations all through the pipeline, one would expect to see some synchronisation code. But where are they? I had to look for a while to see them.

ASP.NET Web API - from what I have learnt from the source code - uses two modern synchronisation mechanisms (rather than classic WaitOne, WaitAll):

  • Task.ContinueWith<T>: this will ensure that the continuation will run in case of successful running of the task. So basically the thread that created the task does not have to wait instead it can define a piece of continuation code to run at the end of the task -  so the synchronisation in fact happens on the background thread. There are numerous places where this technique is used.
  • SynchronizationContext.Post: This is a low level synchronisation technique that is useful only if SynchronizationContext.Current is set.
SynchronizationContext.Current is very important and it synchronises tasks (when they are asynchronous) with the ASP.NET Thread.


Task continuation is a clever synchronisation. Surely the continuation has to wait for the task to finish but the creator of the task has to wait for neither the task nor its continuation. And analogy is the car in the repair garage. If I leave the car in the garage for repair, they will call me to pick up the car - which can be anytime and perhaps I might be too busy to pick it up. But if I ask them to call my wife to pick up the car, my work will not be interrupted - not that my wife will accept to do this favour! It is just an example.

Conclusion

ASP.NET Web API actions (and all the pipeline methods) will be called asynchronously only if you return a Task or Task<T> . This might sound obvious but none of the pipeline methods with Async suffix will run in their own threads. Using blanket Async could be a misnomer. [UPDATE: ASP.NET team indeed have confirmed that the Async is used to denote methods that return Task and can run asynchronously but do not have to]

ASP.NET Web API uses Task continuation for synchronisation. In essence this synchronises the continuation with the background thread in another background thread.

Disclaimer

This article is the result of exploratory debugging of the Web API source code. Some of the information provided might not be accurate but I will make sure the post is updated and maintained if corrections are fed back to me.


Saturday, 7 April 2012

ASP.NET Web API beta Source code: Survival Guide

[Level T2]
NOTE on 01/06/2012: ASP.NET Web API RC was released last night (31/05/2012). This means for a while at least, you do not have to build the nightly releases. You can download it from here.

Just a quick note that as you probably know, ASP.NET Web API beta (along with ASP.NET MVC 4 beta) is out. Scott Guthrie announced the release in his blog on 27th of March and it has been released under Apache 2.0 license.

You may download the source code from here via git or web . This is a really good news for all who wanted to have a deep dive into the implementation and extensibility points of the framework - including me. The media was also surprised on the release as it shows perhaps another shift in Microsoft towards community-oriented software development - but I will leave this subject for another occasion.

It is interesting that the source code comes with full unit testing coverage, yet it does not use MS Test framework available in Visual Studio instead it uses xUnit, a framework among whose contributors is Brad Wilson. This gives us a bit more insight into the way ASP.NET team work who are arguably among the most popular teams in Microsoft.

Downloading the source is all fine. Yet I had a few teething issues with getting it working which I share so that others having similar problems could find their way out.

Building the framework source code

OK, as soon as you have downloaded and unzipped the source, just open the solution. Since this source relies heavily on NuGet packages yet it does not contain binaries, it needs to re-download the packages. There are instructions on the page but I personally could not get it working. 

So first thing to do is to right-click on the solution and click on "Enable NuGet Package Restore" as below [UPDATE: You actually can ignore this step, and do not have to set this value. I managed to build without this step]:


Now, if you attempt to build, you will get the error below:

error : NuGet package restore is not currently enabled. For more information, please see: http://aspnetwebstack.codeplex.com/wikipage?title=NuGet+Packages

Solution is to go to Tools -> Options -> Package Manager -> Package source and add the address below:

http://www.myget.org/F/f05dce941ae4485090b04586209c8b08/
Now you need to rebuild the packages as advised in the ASP.NET web stack page:

build RestorePackages

And now finally rebuild the solution and this time it will work. As the link above describes, this NuGet feed is not quite official and is used for out of band releases - which this source code certainly is.

Now you might get this error again if you try rebuilding having added the new NuGet feed. Not to worry, delete the source code, unzip again, Enable NuGet Package Restore and then build. This time should work.

Using Web API Source code

One of the best ways to understand a source code is to see it running and debugging it. And that is what I tried to do. 

I had already installed ASP.NET Web API/MVC beta from the installer. So here is what I did: created an ASP.NET Web API project (see Part 1 for more details), added the project to the Web API source code, removed references to the ASP.NET Web API/MVC beta DLLs and added project reference to those DLLs I needed from its source. Easy! Well, not so fast...

The problem is if you have installed the ASP.NET Web API, all binaries are already GACed and they take precedence over the project references. You can verify this by looking at the list of DLLs loaded in the output window while debugging. Now this by itself is not a problem, but considering the source to be newer with breaking changes, it becomes a different matteeeerrr...

Now courtesy of Christoph De Baene, this also has a solution. I was lucky to find about his post just from yesterday as he was quicker to see the problem and find a solution. He explains about using Environment variable so CLR looks the development path first:

To resolve this problem we can use DEVPATH. It’s an environment variable that you can set to a folder (typically you’re output folder). The runtime will use the DEVPATH folder for probing before looking into the GAC!

Setting DEVPATH environment variable


You also need to add the entry below to your config file (app.config or web.config depending on your project):
 

 <configuration>
   <runtime>
      <developmentMode developerInstallation="true"/>
   </runtime>
 <configuration>
 
OK, now it is time to run the code. Well, I ended up using Christoph's code but still having issues this time "Method not found":

Method not found: 'Boolean System.Net.Http.Headers.HttpHeaders.TryAddWithoutValidation(System.String, System.String)'.

Well, it turns out this time that the version of the System.Net.Http DLL has also moved on and I used the one coming with the installer. However, while Microsoft has decided not to include this assembly's source code along with the rest, source has indeed moved on and you need to use the one in the packages folder underneath the solution.

Now I did that and still not working! I was pulling my hair out and went through a few things and realised references were not set to "Copy Local". Once I set that to true, it started working.

Conclusion

The process of building and running the ASP.NET Web API (and MVC) is a bumpy ride. There are quite a few additional things you have got to do to get it working.

In brief, here are the steps you need to do to be able to debug the source code if you have installed ASP.NET Web API beta installer (see above for details):
  1. Create a DEVPATH environment variable and set to your debug output folder
  2. Add an entry to your config to flag VS to use DEVPATH
  3. Make sure all your references are "copy local" set to true
  4. Make sure you add reference System.Net.Http.dll using "Manage NuGet packages" and not from the GAC