Use a Message Handler to Set ASP.NET Web API’s Current Thread Culture

ASP.NET Web API provides very streamlined support in the framework to handle content negotiation. In HTTP specs, following Accept series of headers are used in a HTTP client to set in the request for content:

ASP.NET Web API supports first two headers out of the box. The framework itself would select the right MediaTypeFormatter class based upon the Accept header, and a selected MediaTypeFormatter is able to handle Accept-Charset to return the result in the right character set. For example, when a HTTP client sends

The Web API framework will select JsonMediaTypeFormatter as the media type formatter for the response of this request. In turn JsonMediaTypeFormatter is able to take advantage of the backing library JSON.NET and returns the JSON serialization result in the right character set.

As stated in the link above, Accept-Language is not yet automatically supported in the framework. Web API provides several nice extension points to solve such a problem.

Checking the Pipeline

Picking an extension point of such a feature may not be the easiest thing to do. The Web API has the following extension points in the order of execution when the HTTP server receive a request:

  • Global message handlers
  • Per-route message handlers
  • Authorization filters
  • Action Filters

If we consider the importance of current thread’s Culture — when we choose to change the current thread’s culture, all subsequent calls to format dates, numbers, currencies and retrieving resources will return different results — I would like changing current thread’s culture to be as early as possible.

Here is a snapshot from the following chart:

Screenshot 2014-04-25 20.34.45

The chart shows very clearly that the earliest extension point to an incoming request is the global message handler queue. We can certainly implement a custom message handler, insert it into this queue and ask Web API to use this custom message handler to process the HTTP header first.

Implementing the Message Handler

Here is the message handler:

As stated in the HTTP protocol, Accept-Language uses quality values to note the request’s preferences of languages. The first part of code above prioritizes languages based upon quality. The second part finds an available language. The third part sets the thread culture.

Now we have the message handler ready, we can insert this message handler into the pipeline:

This should be implemented in your WebApiConfig.Register() method, and get called when the Web API application starts.