I recently stumbled across a [comparison of JSON serialization libraries][1]. which shows that ServiceStack.Text by far outperforms any of the competitors. Indeed, the folks down at [ServiceStack][2] have been building a lot of great stuff for the past few (4?) years to facilitate their framework.
ServiceStack.Text is available [on Nuget][3] and can be used outside of ServiceStack, within any .NET project, so why not use it with Web API, replacing the default serializer, JSON.NET?
Let’s do that.
Creating a ServiceStack.Text MediaTypeFormatter 🔗
Typically, whenever you want to introduce a new serialziation mechanism to ASP.NET Web API, you’d create a new MediaTypeFormatter. This case is no different. Let’s grab ServiceStack.Text [from Nuget][3]:
PM> Install-Package ServiceStack.Text
Once you have it refrenced in your solution, the formatter is pretty straight forward:
public class ServiceStackTextFormatter : MediaTypeFormatter
{
public ServiceStackTextFormatter()
{
JsConfig.DateHandler = JsonDateHandler.ISO8601;
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true));
SupportedEncodings.Add(new UnicodeEncoding(bigEndian: false, byteOrderMark: true, throwOnInvalidBytes: true));
}
public override bool CanReadType(Type type)
{
if (type == null) throw new ArgumentNullException("type");
return true;
}
public override bool CanWriteType(Type type)
{
if (type == null) throw new ArgumentNullException("type");
return true;
}
public override Task
<object>
ReadFromStreamAsync(Type type, Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)<br /> {<br /> var task = Task
<object>
.Factory.StartNew(() => JsonSerializer.DeserializeFromStream(type, readStream));<br /> return task;<br /> }</p>
<p>
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, System.Net.Http.HttpContent content, TransportContext transportContext)<br /> {<br /> var task = Task.Factory.StartNew(() => JsonSerializer.SerializeToStream(value, type, writeStream));<br /> return task;<br /> }<br /> }<br /> ```
</p>
<p>
We tell the formatter a few things:<br /> - we will support <i>application/json</i> media type<br /> - we support UtF-8 and Unicode encoding<br /> - Read and Write is available for all types of objects<br /> - we tell ServiceStack to handle dates as <i>ISO8601</i>, to avoid JSON dates with Unix Epoch milliseconds (read more <a href="http://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx">here</a>)<br /> - in the read/write methods we simply asynchronously call the respective methods of the ServiceStack.Text.JsonSerializer
</p>
<h3>
Replacing JSON.NET
</h3>
<p>
Now, in order to wire this up, we need to remove the default JSON formatter (JSON.NET) and inject our new formatter into the <i>GlobalConfiguration.Formatters</i> collection.<br /> ```csharp
<br /> public static void Register(HttpConfiguration config)<br /> {<br /> config.Formatters.RemoveAt(0);<br /> config.Formatters.Insert(0, new ServiceStackTextFormatter());
</p>
<p>
//continue with config<br /> }<br /> ```
</p>
<p>
And that's it!
</p>
<p>
From now your ASP.NET Web API application will be using ServiceStack.Text, a serializer which benchmarks show is almost 2x faster than JSON.NET. In all fairness, that's one of the micro optimizations, but still, if you can improve something, why not do that?
</p>
[1]: http://theburningmonk.com/2012/11/json-serializers-benchmark-updated-including-mongodb-driver/
[2]: http://www.servicestack.net/
[3]: https://www.nuget.org/packages/ServiceStack.Text