ROMANCE DAWN for the new world

Microsoft Azure を中心とした技術情報を書いています。

ASP.NET Web API で Jil JSON Serializer を使ってみる

この記事は、ASP.NET Advent Calendar 2014 の2日目の記事です。

qiita.com

「ASP.NET Web API の パフォーマンスを改善するための8つの方法」というブログから、JSON のシリアライズを高速化する方法として、MediaTypeFormatter を Jil JSON Serializer  に置き換える方法を紹介します。

blog.developers.ba

blog.developers.ba

Jil JSON Serializerとは

Jil JSON Serializer は、高速に JSON をシリアライズできるライブラリです。ASP.NET Web API の JSON シリアライズは、デフォルトで JSON.NET が使われており、事実上 .NET の標準 JSON Serializer と言えるライブラリですが、GitHub にあるベンチマーク結果を見ると、JSON.NET などのライブラリと比較して高速であることが分かります。使いかたはシンプルで、NuGet からインストールし、Jil.JSON クラスの Serialize() と Deserialize() を呼び出すだけです。

MediaTypeFormatter を置き換える

Visual Studio 2013 で、WebApplication のプロジェクトを選択し、Web API のテンプレートで作成します。Jil JSON Serializer の C# 用ライブラリの NuGet パッケージをインストールします。

  • Install-Package Jil

Jil JSON Serializer を使った MediaTypeFormatter を作成します。

#JilFormatter.cs
public class JilFormatter : MediaTypeFormatter
{
    private readonly Options _jilOptions;
 
    public JilFormatter()
    {
        _jilOptions = new Options(dateFormat: DateTimeFormat.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, HttpContent content, IFormatterLogger formatterLogger)
    {
        using (var reader = new StreamReader(readStream))
        {
            return Task.FromResult(JSON.Deserialize(reader, type, _jilOptions));
        }
    }
 
    public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
    {
        using (TextWriter streamWriter = new StreamWriter(writeStream))
        {
            JSON.Serialize(value, streamWriter, _jilOptions);
            return Task.FromResult(writeStream);
        }
    }
}

デフォルトの JSON Serializer を削除して、JilFormatter に置き換えます。

#WebApiConfig.cs
public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Formatters.RemoveAt(0);
        config.Formatters.Insert(0, new JilFormatter());
 
        config.MapHttpAttributeRoutes();
 
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

まとめ

ASP.NET Web API では、今回の MediaTypeFormatter の置き換えのように、Framework 側で提供される機能のカスタマイズが簡単にできます。開発者は、Microsoft が提供するライブラリだけでなく、自分の好きなライブラリを自由に組み合わせて、Application を作ることができます。この One ASP.NET の思想が ASP.NET 5(旧 ASP.NET vNext )にも引き継がれて、さらに進化して使いやすくなっていくことを期待しています。