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);