将 .NET Core 2.0 的默认 JSON 解析器替换为
2017-12-07 本文已影响260人
缺水的海豚
前一篇文章 做了 .NET Core 的默认 JSON 输出解析器的替换,经过一段时间的使用,现将 输入/输出 全部用 Jil 替换。
记得之前有人问,如何识别已经成功使用 Jil 解析了,这里提供一个简单的识别方法:
- 默认的 JSON.net 解析器,不做任何配置,在解析
DateTime
的时候,输出的是带时区的时间格式,如:2017-10-01T12:19:24.3096176+08:00- 使用 Jil 替换后,按照文中
Options
配置,输出的是 Unix 时间戳,如:1506831564
新的实现方法,继承自 IInputFormatter
、IOutputFormatter
。
.NET Core 2.0 实现全步骤
- 新建
Formatter
相关的类。- 修改
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<InputFormatterResult> 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());
});
}
至此,全部修改都做完了。