Introduction
In this article we describe how to implement the content negotiation in the ASP.NET Web API.
Content negotiation is used to determine the best way for representing a response when there are multiple possible representations available. It finds the representation for sending the response. There are some mechanisms for content negotiation; they are:
- Accept: It is defined as the media type that are acceptable for the response. For example JSON and XML.
- Accept-Charset: It is defined as the acceptable character set for the response. For example UTF-8 etcetera.
- Accept Encoding: It is defined as the type of content encoding that are acceptable for the response. For example gzip.
- Accept Language: It is defined as the preferable language for the response.
Serialization
Serialization means to serialize the value by the pipeline, such as the value that is given by the Web API and the the pipeline that serializes that value and used as a response.
Let's see an example of the controller:
public Item GetItemById(int sn)
{
var mat = items.FirstOrDefault((m) => m.id ==sn);
if (mat == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return mat;
}
The client might send the request:
GET http://localhost:21374/api/item/1/Http/1.1
Host:localhost:21374
Accept: ApplicationException/json,text/javascript
The server gives the response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 56
Connection: Close
{"sn":1,"Name":"apple","type":"fruit","cost":100}
The object of the HttpResponseMessage can be returned by the controller. If there is a need for a CLR object in the response then we invoke the CreateResponse method.
public HttpResponseMessage GetItem(int sn)
{
var item = items.FirstOrDefault(m => m.id == sn);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return Request.CreateResponse(HttpStatusCode.OK, item);
}
There is an object of the MediaTypeFormatter class, that is the media formatter that is used to serialize the value. It is provided for JSON and XML.
Working of Content negotiation
For the content negotiation there is a service that works that is called IContainerNegotiator, we can get this service from the HttpConfiguration.
Now the pipeline invokes IContentNegotiator.Negitiate and it transfers to the:
There is the information that is returned by the Negotiate in two parts.
The following code defines how the controlter calls the content negotiation.
public HttpResponseMessage GetItem(int sn)
{
var item = new Item()
{ id = sn, Name = "Apple", Type = "fruit", cost = 100 };
IContentNegotiator nego = this.Configuration.Services.GetContentNegotiator();
ContentNegotiationResult ans = nego.Negotiate(
typeof(Item), this.Request, this.Configuration.Formatters);
if (ans == null)
{
var Res = new HttpResponseMessage(HttpStatusCode.NotAcceptable);
throw new HttpResponseException(Res));
}
return new HttpResponseMessage()
{
Content = new ObjectContent<Item>(
item,
anst.Formatter,
ans.MediaType.MediaType
)
};
}
Default Content Negotiator
When we use this class we have no need to implement the IcontentNegitiator because it is performed by the default implementation.
When we invoke MediaTypeFormattor.CanWriteType it clarifies whether the formatter can serialize the type.
To match the formatter to the HTTP request, the content negotiator checks two things of the formatter, they are:
- SupportMediaType: The collection of support media type.
- MediaType Mapping: Has the collection of objects of the media type mapping that gives the way for performing the matches with the media type.