Web API Content Negotiation

ASP.NET Web API Content Negotiation

In this article, I am going to discuss Web API Content Negotiation with an example. From the rest architecture point of view, it is very important to understand the concept of Content Negotiation in Web API. Please read our previous article where we discussed ASP.NET Web API Service using SQL Server database. Let us start the discussion of Web API Content negotiation. We know that there are three pillars of the internet and they are:

  1. The resource
  2. The URL
  3. The representation

The first two are (i.e. the resource and the URL) very straightforward but the last one (i.e. the representation) is a little confusing to understand. The representation is very important in the modern web. Why? Because people are currently not only using Desktop computers to browse the web, but they also are using various types of devices (tab, mobile, etc.) to consume web applications. And the important and the interesting fact is that all these various devices expect the data in various formats.

For example, a few want the data in normal HTML format and some want the data in a normal text format. Others may need the data in JSON format and still some other wants the data in XML format.

We can define the Web API Content Negotiation asthe process of selecting the best representation for a given response when there are multiple representations available”.

One of the standards of the REST service is that the client should have the ability to decide in which format they want the response – whether they want the response in XML or JSON etc. This is called Content Negotiation.

Now, the fact should be clear that “Web API Content Negotiation” means the client and server can negotiate. Always It is not possible to return data in the requested format by the Server. That’s why it is called negotiation, not demand. In such cases, the Web API Server will return the data in the default format.

The question that comes to our mind is how does the Web API know what the client expects?

This is done by checking below the header of the request object.

Content-type: The content type header request to the Web API Server to represent data in this type. The values for Content-type includes “application/jsonandapplication/xml” etc.

Accept: The Accept header specifies the media types which are acceptable for the response, such as “application/json” and “application/xml” or any other custom media type such as “application/vnd.dotnettutorials.employees+xml“.

Accept-Charset: The Accept-Charset header specifies that which character sets are acceptable, such as UTF-8 or ISO 8859-1.

Accept-Encoding: The Accept-Encoding header specifies that which content encodings are acceptable, such as gzip.

Accept-Language: The Accept-Language header specifies the preferred natural language support, such as “en-us“.

Those are the headers of the request object for the request to the server to represent data in the requested way if possible.

In this article, we’ll look at how Web API uses the Accept headers.

A request that is sent to the server includes an Accept header. Using the Accept header and Content-Type the client can specify the format for the response. For example

Content-Type: application/xml returns XML

Content-Type: application/json returns JSON Accept: application/xml returns XML

Accept: application/json returns JSON

Depending on the Accept header and Content-Type value in the request object, the server sends the response. This is called Web API Content Negotiation. 

Fine, so let’s proceed to the example.

In this article, we are going to work with the same example that we started in our previous article where we discussed the step by step procedure of working with SQL Server.

Below is our controller
namespace EmployeeService.Controllers
{
    public class EmployeesController : ApiController
    {
        public IEnumerable<Employee> Get()
        {
            using (EmployeeDBContext dbContext = new EmployeeDBContext())
            {
                return dbContext.Employees.ToList();
            }
        }
        public Employee Get(int id)
        {
            using (EmployeeDBContext dbContext = new EmployeeDBContext())
            {
                return dbContext.Employees.FirstOrDefault(e => e.ID == id);
            }
        }
    }
}

Now run the web API application.

Understanding Content Type in Request Header

Request data in JSON format

The JSON format is currently the most popular format of data representation. So, first, we will see how to return the data in JSON format from the Web API. We are using a tool called Fiddler to test the API services. So please read how to use Fiddler to test web API tutorial before proceeding to this article.

Here is our HTTP header information to get the employee details whose id is 1.

Select the Compose Tab. Then select the HTTP verb as GET. Then provide the URL and click on the Execute button as shown in the below image.

Content Negotiation in Web API

Here you can see that we did not set the Content-Type header value to request the data in JSON format but the Web API returning the data in JSON format. The reason is by default the Web API will return the data in JSON format if we do not specify any “Content-Type” header in the request. See the following output.

Content Negotiation in Web API

And obviously, we can also modify the header value like the following to get the data in JSON format.

Content Negotiation in ASP.NET Web API

Both requests will give us the same output in reality.

Request data in XML format

In this example, we will request the Web API to return the data in XML format. When the application used SOAP-based messages (it’s not that SOAP is obsolete in modern applications, it’s still there but people like to use smarter JSON rather than too much informative and stuffy XML).

Now to get the data in XML format we need to set the Content-Type header of the Http Request to application/xml as shown below.

Content Negotiation in Web API

Once you click on the execute button, you will get the data in XML format as shown in the below image.

ASP.NET Web API Content Negotiation

The above two are the formats (i.e. JSON and XML) that the Web API supports by default. If you want various types of representations then you need to implement a media type formatter in the Web API.

Understand Accept Header in Http Request

In our previous examples, we saw how a content-type header works with Http Request. In this example, we will understand the “Accept” header of the Http Request.

By checking the “Accept” header value, the Web API understands which represent the client is able to accept. For example, if we specify that the client can understand the following representations: application/xml , application/json, text/javascript Then the Web API will return the data in JSON format, the reason is JSON is the default format of the Web API, although the client’s first preference is the XML format. We will prove it with a small example. Have a look at the following screen.

Request With Accept Header:

Web API Content Negotiation

And the output will be

Content Negotiation in Web API

Understand Accept-Language header

In the Accept-Language header, we can specify the preferred language that we want to get from the Web API application. The Accept-Language header is used as in the following:

Accept-Language: en-IN, en-US

The above Accept-Language header indicates that my first choice of language is Indian English but if that is not possible then please give me US English and if that is not possible then please provide the data in the default language.

So Web API Content negotiation is a mechanism, or algorithm, used to determine, based on the client’s request, which media type formatter is going to be used to return an API response.

In the next article, we will discuss what is media type formatter and how it works with an example.

So what does the Web API do when we request for data in a specific format?

The controller in Web API first generates the data that we want to send to the client. For example, if we have asked for the list of employees. The Web API Controller generates the list of employees, and hands the data to the Web API pipeline which then looks at the Accept header value and depending on the format that the client has requested, the Web API will choose the appropriate formatter. For example, if the client has requested for the data in XML format, then Web API uses XML Formatter. similarly, if the client has requested the data in JSON format, then Web API uses JSON Formatter. These formatters are called Media Type Formatters.

ASP.NET Web API is greatly extensible. This means we can also plug-in our own formatters, for custom formatting the data.

Multiple values can also be specified for the Accept header. In this case, the server picks the first formatter which is a JSON formatter and formats the data in JSON.

Accept: application/xml,application/json

You can also specify quality factor. In the example below, XML has a higher quality factor than JSON, so the server uses XML formatter and formats the data in XML.

application/xml;q=0.8,application/json;q=0.5

If you don’t specify the Accept header in the request then by default the Web API returns the data in JSON format.

When the response is sent to the client, notice that the Content-Type header of the response is set to the appropriate value. For example, if the client has requested for application/xml, then the server sends the data in XML format and also sets the Content-Type=application/xml.

The Web API uses the formatters for both request and response messages. When the client makes a request to the server, the client has to set the Content-Type header to the appropriate value to let the server know the format of the data that we are sending. For example, if the client is sending JSON data, the Content-Type header is set to application/json. The server knows it is dealing with JSON data, so it uses JSON formatter to convert JSON data to .NET Type. Similarly, when a response is being sent from the server to the client, depending on the Accept header value, the appropriate formatter is used to convert the .NET type to JSON, XML etc.

We can also very easily change the serialization settings of these formatters. For example, if we want the JSON data to be properly indented and use camel case instead of Pascal case for property names, all we have to do is modify the serialization settings of JSON formatters as shown below. With our example, this code goes in WebApiConfig.cs file in the App_Start folder.

config.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;

config.Formatters.JsonFormatter.SerializerSettings.ContractResolver= new CamelCasePropertyNamesContractResolver();

In the next article, I will discuss Media Type Formatters in Web API with an example.

SUMMARY

In this article, I try to explain ASP.NET Web API Content Negotiation step by step with some example. I hope this article will help you with your need. I would like to have your feedback. Please post your feedback, question, or comments about this article.

3 thoughts on “Web API Content Negotiation”

Leave a Reply

Your email address will not be published. Required fields are marked *