Demystify WebApi Content Negotiation

We will try to understand the real advantages and why it has been introduced. I thought it would be interesting to try to explain the content negotiation in detail.
 

What is content negotiation or conneg?

 
Content negotiation has been defined by W3C. It is the process of selecting the best representation for a given response when there are multiple representations available.
 
Content negotiation (conneg) in the ASP.NET Web API is an intrinsic server-driven mechanism used to determine, based on the client's request, which media type formatter (out of the box there are 4 media type formatters) to be used to return an API response. In general, a client sends the Accept parameter in the Request Header to determine the response. Apart from this, the Web API is smart enough to decide which response format is best. In .NET, it really comes down to deciding how to send down your CLR object to the client, over HTTP or from the ASP.NET Web API perspective, serialization is the process of translating a .NET Common Language Runtime (CLR) type into a format that can be transmitted over HTTP. The default formats are either JSON or XML.
 

Serialization

 
If a Web API controller returns a resource as a CLR type then the pipeline serializes the return value and writes it into the HTTP response body.
 
For example, consider the following controller action, reference MSDN:
  1. public Product GetProduct(int id)  
  2. {  
  3.    var item = _products.FirstOrDefault(p => p.ID == id);  
  4.    if (item == null)  
  5.    {  
  6.       throw new HttpResponseException(HttpStatusCode.NotFound);  
  7.    }  
  8.    return item;  
A client might send this HTTP request:
 
GET http://localhost.:21069/api/products/1 HTTP/1.1
Host: localhost.:21069
Accept: application/json, text/javascript, */*; q=0.01
 
In response, the server might send:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 57
Connection: Close
{"Id":1,"Name":"Gizmo","Category":"Widgets","Price":1.99}
 
In this example, the client requested either JSON, JavaScript, or “anything” (*/*). The server responded with a JSON representation of the Product object. Notice that the Content-Type header in the response is set to "application/json".
 
Before proceeding further, we need to explain two more important terms, around which the content negotiation is built.
  • Media type is defined again by W3C as being used “in the Content-Type and Accept header fields in order to provide open and extensible data typing and type negotiation”. Examples of media type can be application/json, application/xml, application/rss+xml, application/html or text/plain.
  • Media type formatter is a class that writes/reads a CLR object to/from the body of the HTTP response/request (depending on the information flow direction).
The conneg mechanism itself is part of the GlobalConfiguration.Services collection and can be retrieved using the GlobalConfiguration.Services.GetContentNegotiation () method.
 
Conneg formatters are part of the GlobalConfiguration.Formatters collection and as such can be easily accessed from anywhere within your Web API application context.
 
Out of Box Web API ships with 4 formatters, in the following order (order is important since when no good matches can be found, Web API uses formatters in the order they appear).
 
To learn more about how Web API uses MediaTypeFormatter to respond to requests. Though this is the order of handling a request from a MediaType Formatter.
  • System.Net.Http.Formatting.JsonMediaTypeFormatter, based on JSON.NET
  • System.Net.Http.Formatting.XmlMediaTypeFormatter, based on DataContractSerializer
  • System.Net.Http.Formatting.FormUrlEncodedMediaTypeFormatter, for handling HTML form URL-encoded data
  • System.Web.Http.ModelBinding.JQueryMvcFormUrlEncodedFormatter, for handling model-bound HTML form URL-encoded data
How content negotiation is performed
 
In the Web API, there are 4 criteria before deciding on the media formatter to use, in descending order of precedence:
  1. Media Type Mapping
     
    A MediaTypeMapping allows you to map the request or response messages that have certain characteristics to a media-type. Web API ships with the following 4 media type mappings:
     
    • QueryStringMapping,
    • UriPathExtensionMapping,
    • RequestHeaderMapping
    • MediaRangeMapping.
       
  2. Accept headers in the request
     
    Accept headers issued by the client are the second most important criteria. Let's say your client makes a request and includes the following headers entry. This request is handled by Conneg.
     
     
  3. Content-type of the body
     
    The next in line is the content type of the request. If the request incoming to the Web API is of a specific content type (contains a specific media type like application/json,application/xml) and either MediaTypeMappings decides otherwise or Accept headers are not present then the conneg algorithm resorts to inspecting the Content-Type of the request.
     
    Note: If both Accept and Content-Type are present, obviously Accept takes precedence.
     
  4. Checking if the formatter can serialize the response content's model
     
    If, for a given request, any of all the preceding 3 criteria don't match then the conneg mechanism simply starts going through all the available formatters in the GlobalConfiguration.Formatters collection in the order they are stored there and checks whether the return type can be written by each formatter.
     
    The first formatter that can serialize the type is chosen or on the first match, the search process is terminated and the matched formatter is used by Web API to return the response to the client.
     
    or
     
    I hope after reading this you may be able to understand the content negotiation.