FormatFilter and MediaTypeMappings in ASP.NET Core 1.0 MVC

Β· 535 words Β· 3 minutes to read

In the earlier posts, we looked at how formatters work in general in the upcoming MVC Core 1.0 (although at that time it was still being referred to as MVC 6) and how XML formatters can be enabled in your ASP.NET Core application.

This time around, I thought it would be interesting to follow up on that, and discuss another topic that should be very familiar to folks with ASP.NET Web API experience - MediaTypeMappings. They were quite commonly used in Web API, and they have been ported over to MVC Core, and can be enabled via a FormatFilter.

MediaTypeMappings πŸ”—

I have blogged about the role of media type mappings in Web API before. To quickly remind you about them, they allowed you to override the content negotiation process with some arbitrary querystring or route parameter, for example:

http://my.api.com/books/1?return=xml  
http://my.api.com/books/1.xml  

This was especially useful if you wanted to disguise the deynamically generated response to appear as a file for the caller - for example .pdf or .csv.

You can configure MediaTypeMappings in ASP.NET Core MVC by modifying the MvcOptions at your application startup. This is shown below.

public void ConfigureServices(IServiceCollection services)  
{  
var mvcBuilder = services.AddMvc(opt =>  
{  
opt.FormatterMappings.SetMediaTypeMappingForFormat("pdf", new MediaTypeHeaderValue("application/pdf"));  
});  
}  

In other words, what you are simply saying, is that given an arbitrary string (say pdf), that will appear in the URL (as special querystring or route value - more on that in a moment), always return the response with a specific predefined media type, regardless of what the content negotiation would have produced in this case. You also have to make sure that a relevant foramtter, capable of producing a payload with a given media type is registered - otherwise things will obvoiusly not work.

To illustrate this, consider the following XML example:

public void ConfigureServices(IServiceCollection services)  
{  
var mvcBuilder = services.AddMvc(opt =>  
{  
opt.FormatterMappings.SetMediaTypeMappingForFormat("xml", new MediaTypeHeaderValue("application/xml"));  
});  
}  

This is not going to do anything, because the XML formatters are not registered by default in ASP.NET Core 1.0 MVC. Instead, you have to explicitly enable them by referencing Microsoft.AspNet.Mvc.Formatters.Xml Nuget package and updating your code to enable the new formatters:

public void ConfigureServices(IServiceCollection services)  
{  
var mvcBuilder = services.AddMvc(opt =>  
{  
opt.FormatterMappings.SetMediaTypeMappingForFormat("xml", new MediaTypeHeaderValue("application/xml"));  
});  
mvcBuilder.AddXmlDataContractSerializerFormatters();  
}  

We are almost there, but for the mapping to kick in, you also need to use a FormatFilter.

FormatFilter πŸ”—

In order for media type mappings to be picked up by the framework you also have to annotate your controller with a FormatFilter (you could also register it globally).

[FormatFilter]  
public class BooksController : Controller  
{  
[Route("[controller]/{id}.{format?}")]  
public Book GetProduct(int id)  
{  
return new Book { Id = id, Title = "foo"};  
}  
}  

FormatFilter will inspect the URL of the request for a format string (in querystring or route values) and then compare the value to the values registered at the media type mappings. If there is a match, the given media type mapping will kick in and the response returned to the client will be in a media type you pre-defined - effectively bypassing the regular content negotiation process (so inspecting Accept header and so on).

The above controller will therefore react to the following URLs requested by the client:

http://my.api.com/books/1?format=xml  
http://my.api.com/books/1.xml  

About


Hi! I'm Filip W., a cloud architect from ZΓΌrich πŸ‡¨πŸ‡­. I like Toronto Maple Leafs πŸ‡¨πŸ‡¦, Rancid and quantum computing. Oh, and I love the Lowlands 🏴󠁧󠁒󠁳󠁣󠁴󠁿.

You can find me on Github and on Mastodon.

My Introduction to Quantum Computing with Q# and QDK book
Microsoft MVP