【问题标题】:ASP.Net Core 2.2 - separate serializer settings for input and outputASP.Net Core 2.2 - 输入和输出的单独序列化器设置
【发布时间】:2020-03-25 04:55:07
【问题描述】:

ASP.Net Core 2.2 允许使用MvcJsonOptions.SerializerSettings 属性设置序列化器设置。问题是它影响输入和输出。有没有办法为输入(反序列化)和输出(序列化)提供单独的选项?特别是,我需要为 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# .net asp.net-core json.net asp.net-core-2.2


    【解决方案1】:

    终于找到了这个解决方法: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>());
    

    在服务提供者配置中

    【讨论】:

      【解决方案2】:

      我会使用 Newtonsoft.Json 中的 JsonSerializerSettings 类来定义两个实例 mySerializeSettingmyDeserializeSettings

      using Newtonsoft.Json;
      using Microsoft.Rest.Serialization;
      
      string requestContent = SafeJsonConvert.SerializeObject(value, mySerializationSettings);
      

      反序列化:

      var result = SafeJsonConvert.DeserializeObject<myclass>(input, myDeserializeSettings);
      

      要了解如何设置序列化设置,请参阅https://www.newtonsoft.com/json/help/html/SerializationSettings.htm

      【讨论】:

      • 我知道如何使用 Newtonsoft.Json 处理它。问题是如何为 ASP.Net Core 2.2 提供不同的设置
      猜你喜欢
      • 1970-01-01
      • 2019-10-01
      • 2021-02-22
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 2019-02-06
      • 1970-01-01
      相关资源
      最近更新 更多