将 ASP.NET MVC5 默认的 JSON 解析器换为 Jil

如果要修改 .NET Core 中的默认 JSON 解析器,请看这里

在 ASP.NET MVC 中,默认的 JSON 解析器(序列化和反序列化)是 Json.NET(主页、Github、Nuget)。

在网上看到很多建议将解析器换为 Jil(Github、Nuget)。由于 JSON 的解析是 MVC 的关键步骤,所以,如果能将 JSON 的解析器更换为性能更好的之后,性能必将得到进一步的提升。

关于 Json.NET 和 Jil 的性能对比,我这里就没有再做了,套用老外的一个测试结果(原文),大致情况如下:

将 ASP.NET MVC5 默认的 JSON 解析器换为 Jil_第1张图片
JSON 解析性能测试

各组件版本:Jil(1.5.0)、ServiceStack.Text(4.0.22)、Json.Net(6.0.3)、fastJson(2.1.1.0)、MongoDB Drive(1.9.1)、System.Json(4.0.20126.16343)、System.Text.Json(1.9.9.1)、JsonFx(2.0.1209.2802)、JayRock(0.9.16530)

事实上,通过上图可以看出,性能最好的当属 Google 的 Protocol Buffers(主页、Github、ProtoBuf-net(Nuget))。但是,由于该数据格式不是 JSON,所以,前端技术(如:Javascript等)暂无法解析该数据格式,不能使用。不过,有兴趣的可以自行了解 Google 的该高性能组件。

接下来,正式使用 Jil 替代默认的 Json.NET。

由于 Jil(Github、Nuget)是基于 Sigil(Github、Nuget)的,所以,在 Nuget 中,添加 Jil 引用的时候,会自动将 Sigil 也引用进来。

添加好引用之后,建立一个 JilFormatter 的类,继承自 MediaTypeFormatter

命名空间如下所示:

using Jil;

using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

类中的代码如下所示:

// Jil 解析器
public class JilFormatter : MediaTypeFormatter
{
    private readonly Options _jilOptions;

    public JilFormatter()
    {
        _jilOptions = new Options(dateFormat: DateTimeFormat.MillisecondsSinceUnixEpoch,
                                  excludeNulls: true, includeInherited: true,
                                  serializationNameFormat: SerializationNameFormat.CamelCase);

        SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
        SupportedEncodings.Add(new UTF8Encoding(false, true));
        SupportedEncodings.Add(new UnicodeEncoding(false, true, 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 ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
    {
        return Task.FromResult(DeserializeFromStream(type, readStream));
    }

    private object DeserializeFromStream(Type type, Stream readStream)
    {
        try
        {
            using (var reader = new StreamReader(readStream))
            {
                var method = typeof(JSON).GetMethod("Deserialize", new Type[] { typeof(TextReader), typeof(Options) });
                var gen = method.MakeGenericMethod(type);
                return gen.Invoke(this, new object[] { reader, _jilOptions });
            }
        }
        catch
        {
            return null;
        }
    }

    public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
    {
        using (var writer = new StreamWriter(writeStream))
        {
            JSON.Serialize(value, writer, _jilOptions);
            return Task.FromResult(writeStream);
        }
    }
}

建立好上述解析器之后,在 Global.asax.cs 的 Application_Start 中去注册新的解析器,就可以了,代码如下:

void Application_Start(object sender, EventArgs e)
{
    // 更换为 Jil 解析器
    var config = GlobalConfiguration.Configuration;
    config.Formatters.Remove(config.Formatters.JsonFormatter);
    config.Formatters.Insert(0, new JilFormatter());

    // 其它代码
}

至此,全部工作已经完成,默认的 JSON 解析器已经替换为 Jil,重新编译发布,就OK了。

你可能感兴趣的:(将 ASP.NET MVC5 默认的 JSON 解析器换为 Jil)