Adding a custom MediaTypeFormatter to your WebAPI project
Adding a custom MediaTypeFormatter to your WebAPI project

Adding a custom MediaTypeFormatter to your WebAPI project

2014, Apr 30    

This is going to be easy. As many of the other posts of this blog, even this entry is due to an issue I was forced to face, this time with the marvelous IE8 😀
In a nutshell, I have a WebAPI project returning some nice json data. Everything works fine, except when you try to access the api via Ajax + IE8…the browser is somehow refusing to perform the ajax call due to the fact that the content type “application/json” in the response header is not recognised. Damn.

What I had to do is adding a custom MediaTypeFormatter that returns the json data using “text/plain”, and then on client side parse the resulting string using some library like this one.

Here’s the code of the formatter:

[csharp]
public class PlainTextMediaTypeFormatter : MediaTypeFormatter
{
const string supportedMediaType = “text/plain”;

public PlainTextMediaTypeFormatter()
{
this.AddQueryStringMapping(“format”, “plain”, new MediaTypeHeaderValue(supportedMediaType));
}

public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
}

public override bool CanReadType(Type type)
{
return false;
}

public override bool CanWriteType(Type type)
{
return true;
}

public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
using (var writer = new StreamWriter(writeStream))
{
var jsonData = string.Empty;
if (null != value)
jsonData = Newtonsoft.Json.JsonConvert.SerializeObject(value);

writer.WriteLine(jsonData);
}

var tcs = new TaskCompletionSource();
tcs.SetResult(null);
return tcs.Task;
}
}
[/csharp]

The code is pretty easy, we can split it into 2 main parts:
1) use MediaTypeFormatterExtensions.AddQueryStringMapping to register custom querystring parameter, telling the WebAPI engine to use this media formatter (for example: http://mywebapi.com/products?format=plain)
2) in the WriteToStreamAsync method just serialize the input value to json and write it to the output stream as string (I am using the terrific Newtonsoft Json library for this)

BONUS:
if you don’t like adding more querystring parameters,  the MediaTypeFormatterExtensions class exposes other two methods, AddRequestHeaderMapping and AddUriPathExtensionMapping.

Enjoy!