Saturday, February 24, 2018

Content Negotiation in Web API


What is Content Negotiation?

One of the standards of the RESTFul services is that the client should be able to decide the format of the response they want from the server. E.g. does that client want to response in JSON, xml, etc?
When a client sends a request to the server, the request holds accept header. Using this accept header the client can specify the format of the response they want from the server. E.g. if accept header is set to Accept:application/xml, then the server sends the response in xml format. If accept header is set to Accept:application/json, then the response received will be in json format.
When server sends a response in a requested format, it also sets the Content-type header to appropriate value. If the requested format is xml, server sets the Content-type to application/xml and if the requested format is json, it would be set to application/json. So, depending on the value of the accept header in request, the server sends the response. This is called Content Negotiation.
The Web API controller generates the data that we want to send to the client and hand over the data to Web API pipeline which then looks at the accept header and depending on the format specified, Web API will choose the appropriate formatter to format the data. If client has requested xml data, Web API chooses xml formatter and json formatter for json data. These formatters are nothing but classes and these are called MediaTypeFormatter.  We can also create our own custom formatter.
We can also specify multiple formatter in accept header. E.g. if I want both xml and json data, I would specify it as Accept: application/json, application/xml.

We can also specify quality factor in accept header. E.g. Accept: application/json;q=0.4, application/xml;q=0.9. In this case, xml has got higher quality factor than json. So the server sends the data in xml format.
If accept header is not specified, Web API returns the data in json format.
Depending upon the content type specified by the client, the server chooses appropriate formatter. If we set accept header to application/json, the server knows it is dealing with json data and uses appropriate formatter to convert json data to .Net type. These formatters are used by the server for both request and response messages. These formatters are called MediaTypeFormatters.

We can change the settings of these formatters to meet our application’s requirements. Let’s say we want json data to be properly indented or property names should use any particular cases, we can specify it in WebAPICofig.cs file.
Config.formatters.JsonFormatter.SerializerSettings.Formatting = NewtonSoft.Json.Formatting.Indented; 

MediaTypeFormatter is an abstract class from which all the formatters (JsonMediaTypeFromatter, XmlMediaTypeFormatter or custom formatter) are derived from.  

How to return data in a particular format from Web API service?
In WebAPIConfig.cs file’s Register method, add below line of code to return data only in Json format.
config.Formatters.Remove(config.Formatters.XmlFormatter);

This will return the data in only Json format even if accept header is set to application/xml. Similarly if we want the data to be returned in only xml format, we will do
config.Formatters.Remove(config.Formatters.JsonFormatter);

No comments:

Post a Comment