Content negotiation is a process where the server identifies the kind of format that the client supports and depending on the comfort of the client, he sends that format. You might often want to consume your services from various types of devices. A resource may be available in several different representations. For example, it might be available in different languages, different media types or some other combinations. It may be in normal HTML, text, JSON or in XML formats.
How content negotiation works?
Now the question is how does the client communicate to the server and what kind of format does it support? This is achieved by accepting request headers.
This accept request header is sent to the HTTP post or HTTP get and lists all formats it can read. Accept: */* means that client is okay with every content format that the server is able to provide.
So now the client makes a call to the server, it makes an HTTP post call or get call, he sends a content type in the format of a main type and sub type. This essentially means that the client sends Text/HTML , Application/XHTML, Application /XML, Image/JPEG or Image/GIF.
In other words, from the client side, the client says the main type is text and the sub type which it support is XML or the main type is image and the sub type which it support is JPEG. The server interprets these type and depends on the type it sends the output. At this point client and server agree with the format or they don’t. In latter case server gives content out in its default format and it is up to client to get something done with this answer (log an error).
The basic rules can be described as:
- The framework will attempt to return the format that the client asked for using the Accept
- In absence of a specific format requested or inferred, the default format is JSON.
- If the format the client asked for is not available the framework will return the default format JSON. (Example: accept header was application/DoesNotExistFormat)
While consuming a Web API, we don’t have to write a return Json, return Action Result or return HTML , that will happen by itself depending on the accept data which is coming from the client. So just send a list of data and let Web API to decide which format it should return.
Here is a simple GET request from Chrome to localhost:
GET /api/Employee/GetEmployees HTTP/1.1 Host: localhost:53003 Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8
The accept header asks for several formats including application/xml, but does not ask for application/Json. Hence the server will just return the only format it can match which is XML.
So it will return data in XML format like
In contrast if we made the same request with IE it will simply not ask for XML:
Accept: text/html, application/xhtml+xml, */*
Since the browser did not ask for any format that the framework recognizes, it will fallback to the default rule and return JSON data.
Built-in content negotiation helps to serve same content in different formats to different clients. Clients have to say what format they expect and as long as Web API is able to convert results to this format, the client gets content in the format it asked for.