Web API Media Type Formatters

ASP.NET Web API Media Type Formatters

In this article, I am going to discuss the Web API Media Type Formatters with examples. The ASP.NET Web API Media type formatters are the classes which are responsible for serializing the request/response data so that the Web API can understand the request data format and also send data in the format which client expects. 

We are going to work with the same example that we started in ASP.NET Web API using SQL Server article. So please read that article before proceeding to this article.

What are MediaTypeFormatters in Web API?

As we have seen in the previous article that the Web API handles the JSON and XML formats data based on the Accept and Content-Type headers. But, the important question is how does it handle these different formats? The answer is: By using Media-Type formatters.

The Media type formatters are the classes which are responsible for serializing the request/response data so that the Web API Framework can understand the request data format and also send data in the format which client expects.

ASP.NET Web API includes the following built-in media type formatters.

Web API Media Type Formatters

Retrieve Built-in Media Type Formatters:

The Web API Framework includes the above-listed media type formatter classes by default. However, you can also add, remove or change the order of the formatters.

The following example demonstrates an HTTP Get method that returns all built-in formatter classes.

public IEnumerable<string> Get()
{
    IList<string> formatters = new List<string>();
    foreach (var item in GlobalConfiguration.Configuration.Formatters)
    {
        formatters.Add(item.ToString());
    }
    return formatters.AsEnumerable<string>();
}

In the above example, the GlobalConfiguration.Configuration.Formatters returns the MediaTypeFormatterCollection that includes all the formatter classes. The above example returns the names of all the formatter classes as shown in the image below.

ASP.NET Web API Media Type Formatters

Alternatively, the MediaTypeFormatterCollection class defines convenience properties that provide direct access to three of the four built-in media type formatters. The following example shows retrieving the media type formatters using the MediaTypeFormatterCollection’s properties.

public IEnumerable<string> Get()
{
    IList<string> formatters = new List<string>();
    formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter.GetType().FullName);
    formatters.Add(GlobalConfiguration.Configuration.Formatters.XmlFormatter.GetType().FullName);
    formatters.Add(GlobalConfiguration.Configuration.Formatters.FormUrlEncodedFormatter.GetType().FullName);
    return formatters.AsEnumerable<string>();
}

The above example returns following response to the browser.

Media Type Formatters in ASP.NET Web API

Let’s understand Media Type Formatters with an example

From ASP.NET Web API perspective, the serialization is the process of translating a .NET Common Language Runtime (CLR) type into a format that can be transmitted over HTTP. The default format in Web API can be either JSON or XML

A media type formatter that is an object of type MediaTypeFormatter, performs the serialization in the ASP.NET Web API pipeline.

Consider a simple action method handling GET in an ApiController:

public Employee Get(int id)
{
    using (EmployeeDBContext dbContext = new EmployeeDBContext())
    {
        return dbContext.Employees.FirstOrDefault(e => e.ID == id);
    }
}

The above method returns a CLR object of Employee type. In order to return the data contained in the Employee object to the client, the Employee object needs to be serialized. The serialization in ASP.NET Web API application is generally performed by the MediaTypeFormatter.

The Web API Media Type Formatters serializes the object which is going to be returned from the action method into either JSON or XML. Once the Web API Media Type Formatters serializes the data into XML or JSON then these JSON or XML data written into the response message body.

The Web API media type formatters that serialize the object into the JSON and XML are JsonMediaTypeFormatter and XmlMediaTypeFormatter respectively. Both the classes are deriving from MediaTypeFormatter class. The process through which the MediaTypeFormatter is chosen is called content negotiation which we discussed in our previous article in details.

What is Web API MediaTypeFormatter:

The Web API MediaTypeFormatter is an abstract class from which the JsonMediaTypeFormatter and XmlMediaTypeFormatter classes are inherited. JsonMediaTypeFormatter handles the JSON request and response where the XmlMediaTypeFormatter handles the XML request and response.

A resource can have one or more representations. When we issue a GET request to retrieve a resource, such as an employee with ID 1, the response message contains the representation of the resource, for example, any value that specific action returns. The Web API indicates how the resource is represented in the response through the Content-Type response header. The Accept request header can be used by a client to indicate the set of preferred representations for the resource in the response.

By default, the Web API framework supports two media types: JSON and XML. When you issue a request with Accept: application/json, then the response message will be JSON and the Content-Type will be set to application/json. Similarly, if you issue a request with Accept: application/xml, then the response message will be XML and the Content-Type will be set to application/xml.

You can also specify a quality value indicating the relative preference. The range is 0–1, with 0 being unacceptable and 1 being the most preferred. The default value is 1. For example, consider the below header

Accept: application/json; q=0.8, application/xml;q=0.9

Here, the response message will be in XML format because the application/xml has a quality value of 0.9, that is higher than the quality value of 0.8 specified for application/json.

How to return the only JSON from Web API Service irrespective of the Accept header value?

Include the following line in Register() method of WebApiConfig.cs file in the App_Start folder. This line of code completely removes XmlFormatter which forces ASP.NET Web API to always return JSON irrespective of the Accept header value in the client request. Use this technique when you want your service to support only JSON and not XML. 

With this change, irrespective of the Accept header value (application/xml or application/json), the Web API service is always going to return JSON.

config.Formatters.Remove(config.Formatters.XmlFormatter);

How to return only XML from Web API Service irrespective of the Accept header value

Include the following line in Register() method of WebApiConfig.cs file in the App_Start folder. This line of code completely removes JsonFormatter which forces ASP.NET Web API to always return XML irrespective of the Accept header value in the client request. Use this technique when you want your service to support only XML and not JSON.

config.Formatters.Remove(config.Formatters.JsonFormatter); With this change, irrespective of the Accept header value (application/xml or application/json), the Web API service is always going to return XML.

How to return JSON instead of XML from ASP.NET Web API Service when a request is made from the browser?

So here is what we want the service to do

  1. When a request is issued from the browser, the web API service should return JSON instead of XML. 
  2. When a request is issued from a tool like a fiddler the Accept header value should be respected. This means if the Accept header is set to application/xml the service should return XML and if it is set to application/JSON the service should return JSON.
There are 2 ways to achieve this

Approach 1: Include the following line in Register() method of WebApiConfig.cs file in the App_Start folder. This tells ASP.NET Web API to use JsonFormatter when a request is made for text/html which is the default for most browsers. The problem with this approach is that the Content-Type header of the response is set to text/html which is misleading.

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue(“text/html”));

Approach 2: Include the following class in WebApiConfig.cs file in App_Start folder. 
public class CustomJsonFormatter : JsonMediaTypeFormatter
{
    public CustomJsonFormatter()
    {
        this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
    }

    public override void SetDefaultContentHeaders(Type type, HttpContentHeadersheaders, MediaTypeHeaderValue mediaType)
    {
        base.SetDefaultContentHeaders(type, headers, mediaType);
        headers.ContentType = new MediaTypeHeaderValue("application/json");
    }
}

Register the formatter: Place the following line in Register() method of WebApiConfig.cs file in the App_Start folder

config.Formatters.Add(new CustomJsonFormatter());

With these 2 changes, when a request is issued from the browser we will get JSON formatted data and the Content-Type header of the response is also set to application/json. If we are using tools like Fiddler and if we set Accept header to application/xml we will still get XML formatted data.

In the next article, I will discuss CRUD Operations in Web API with an example.

SUMMARY

In this article, I try to explain ASP.NET Web API Media Type Formatters step by step with a simple 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.

1 thought on “Web API Media Type Formatters”

Leave a Reply

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