Saturday, May 3, 2014

Demystify WebApi Content negotiation

Demystify WebApi Content negotiation

In this article we will look into the heart of ASP.Net WebApi content negotiation or conneg. We will try to understand the real advantages and why it has been introduced. I thought it would be interesting to try to explain 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 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 box there are 4 media type formatters ) is going to be used to return an API response.In general client send the Accept parameter in Request Header to determine the response , Apart from this Web API smart enough to decides which repsonse format is best. In .NET, it really comes down to deciding on 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 format I are either JSON or XML.

Serialization

If a Web API controller returns a resource as CLR type, 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;
  9:  }
A client might send this HTTP request:
  1: GET http://localhost.:21069/api/products/1 HTTP/1.1
  2: Host: localhost.:21069
  3: Accept: application/json, text/javascript, */*; q=0.01

In response, the server might send:

  1: HTTP/1.1 200 OK
  2: Content-Type: application/json; charset=utf-8Content-Length: 57
  3: Connection: Close 
  4: {"Id":1,"Name":"Gizmo","Category":"Widgets","Price":1.99}

In this example, the client requested either JSON, Javascript, or “anything” (*/*). The server responsed 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, text/plain
Media type formatter is a class which writes/reads a CLR object to/from the body of the HTTP response/request (depending on the information flow direction).

Conneg mechanism itself is part of 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 know more in how Web API uses MediaTypeFormatter to respond to request.

WebApi: MediaTypeFormatters in WebApi

Manage WebApi Response using Media Types of MediaTypeFormatters

Though this is the order of handling a request from 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 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 4 different 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.

clip_image001

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 specific content type (contains specific media type like application/json,application/xml), and either MediaTypeMappings decide otherwise or Accept headers are not present, 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 above 3 criteria doesn’t match, 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 first match, the search process is terminated and the matched formatter is used by Web API to return the response to the client or

Hope after reading this you may be able to understand the content negotiation.

1 comment :