首页 > 解决方案 > ASP.Net Core 2.2 - 输入和输出的单独序列化器设置

问题描述

MvcJsonOptions.SerializerSettingsASP.Net Core 2.2 允许使用属性设置序列化器设置。问题是它影响输入和输出。有没有办法为输入(反序列化)和输出(序列化)提供单独的选项?特别是,我需要为设置设置不同的行为NullValueHandling:在反序列化客户端 json 时忽略不可空字段的空错误,但在序列化结果时为定义的模型字段保留空值。

例如,我有一个用于请求的 C# 模型:

public class SomeEntity
{
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public string Name { get; set; }
}

并输入 JSON: { id: null, parentId: null, name: "test" }。反序列化失败NullValueHandling.Include但适用于NullValueHandling.Ignore.

但是当我序列化一个像这样的实体时

new SomeEntity
{
    Id = 1,
    ParentId = null,
    Name = "test"
}

它用:保持空值,但用NullValueHandling.Include:{ id: 1, parentId: null, name: "test" }擦除它。NullValueHandling.Ignore{ id: 1, name: "test" }

我需要实现输入的“忽略”场景和输出的“包含”。

标签: c#.netasp.net-corejson.netasp.net-core-2.2

解决方案


终于找到了这个解决方法:https ://github.com/aspnet/Mvc/issues/4562#issuecomment-226100352

public class CustomSerializerSettingsSetup : IConfigureOptions<MvcOptions>
{
    private readonly ILoggerFactory _loggerFactory;
    private readonly ArrayPool<char> _charPool;
    private readonly ObjectPoolProvider _objectPoolProvider;

    public CustomSerializerSettingsSetup(
        ILoggerFactory loggerFactory,
        ArrayPool<char> charPool,
        ObjectPoolProvider objectPoolProvider)
    {
        _loggerFactory = loggerFactory;
        _charPool = charPool;
        _objectPoolProvider = objectPoolProvider;
    }

    public void Configure(MvcOptions options)
    {
        options.OutputFormatters.RemoveType<JsonOutputFormatter>();
        options.InputFormatters.RemoveType<JsonInputFormatter>();
        options.InputFormatters.RemoveType<JsonPatchInputFormatter>();

        var outputSettings = new JsonSerializerSettings();
        options.OutputFormatters.Add(new JsonOutputFormatter(outputSettings, _charPool));

        var inputSettings = new JsonSerializerSettings();
        var jsonInputLogger = _loggerFactory.CreateLogger<JsonInputFormatter>();
        options.InputFormatters.Add(new JsonInputFormatter(
            jsonInputLogger,
            inputSettings,
            _charPool,
            _objectPoolProvider));

        var jsonInputPatchLogger = _loggerFactory.CreateLogger<JsonPatchInputFormatter>();
        options.InputFormatters.Add(new JsonPatchInputFormatter(
            jsonInputPatchLogger,
            inputSettings,
            _charPool,
            _objectPoolProvider));
    }
}

services.TryAddEnumerable(
    ServiceDescriptor.Transient<IConfigureOptions<MvcOptions>, CustomSerializerSettingsSetup>());

在服务提供者配置中


推荐阅读