将 .NET Core 2.0 的默认 JSON 解析器替换为 Jil

前一篇文章 做了 .NET Core 的默认 JSON 输出解析器的替换,经过一段时间的使用,现将 输入/输出 全部用 Jil 替换。

记得之前有人问,如何识别已经成功使用 Jil 解析了,这里提供一个简单的识别方法:

  • 默认的 JSON.net 解析器,不做任何配置,在解析 DateTime 的时候,输出的是带时区的时间格式,如:2017-10-01T12:19:24.3096176+08:00
  • 使用 Jil 替换后,按照文中 Options 配置,输出的是 Unix 时间戳,如:1506831564

新的实现方法,继承自 IInputFormatterIOutputFormatter

.NET Core 2.0 实现全步骤

  1. 新建 Formatter 相关的类。
  2. 修改 Startup.cs 中的 ConfigureServices 方法,在其中增加配置。

直接上代码……

using Jil;

using Microsoft.AspNetCore.Mvc.Formatters;

using System;
using System.Text;
using System.Threading.Tasks;

namespace TestNS
{
    // Formatter 基类
    public abstract class MyFormatter
    {
        protected const string CONTENT_TYPE = "application/json";

        protected readonly Options Opts = new Options(excludeNulls: true, includeInherited: true,
                                                      dateFormat: DateTimeFormat.SecondsSinceUnixEpoch,
                                                      serializationNameFormat: SerializationNameFormat.CamelCase);
    }

    // 输入 JSON 解析类
    public class MyInputFormatter : MyFormatter, IInputFormatter
    {
        private readonly Options _options;

        public MyInputFormatter()
            : this(null)
        { }

        public MyInputFormatter(Options options)
        {
            _options = options ?? Opts;
        }

        public bool CanRead(InputFormatterContext context)
        {
            return true;
        }

        public Task ReadAsync(InputFormatterContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var request = context.HttpContext.Request;

            using (var reader = context.ReaderFactory(request.Body, Encoding.UTF8))
            {
                // 使用 Jil 反序列化
                var result = JSON.Deserialize(reader, context.ModelType, _options);
                return InputFormatterResult.SuccessAsync(result);
            }
        }
    }

    // 输出 JSON 解析类
    public class MyOutputFormatter : MyFormatter, IOutputFormatter
    {
        private readonly Options _options;

        public MyOutputFormatter()
            : this(null)
        { }

        public MyOutputFormatter(Options options)
        {
            _options = options ?? Opts;
        }

        public bool CanWriteResult(OutputFormatterCanWriteContext context)
        {
            return true;
        }

        public Task WriteAsync(OutputFormatterWriteContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var response = context.HttpContext.Response;
            response.ContentType = CONTENT_TYPE;

            if (context.Object == null)
            {
                // 忘了在哪里看的了,192 好像在 Response.Body 中表示 null
                response.Body.WriteByte(192);
                return Task.CompletedTask;
            }

            using (var writer = context.WriterFactory(response.Body, Encoding.UTF8))
            {
                // 使用 Jil 序列化
                JSON.Serialize(context.Object, writer, _options);
                return Task.CompletedTask;
            }
        }
    }
}

Startup.cs 中,做如下修改:

public void ConfigureServices(IServiceCollection services)
{
    // 其它代码

    services.AddMvc().AddMvcOptions(opts =>
    {
        // 使用 Jil 替换默认的 JSON 解析
        opts.InputFormatters.Clear();
        opts.InputFormatters.Add(new MyInputFormatter());
        opts.OutputFormatters.Clear();
        opts.OutputFormatters.Add(new MyOutputFormatter());
    });
}

至此,全部修改都做完了。

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