ASP.Net Core 2.2 - 输入和输出的独立序列化器设置
ASP.Net Core 2.2 - separate serializer settings for input and output
ASP.Net Core 2.2 允许使用 MvcJsonOptions.SerializerSettings
属性 设置序列化器设置。问题是它会影响输入和输出。有没有办法为输入(反序列化)和输出(序列化)提供单独的选项?特别是,我需要为 NullValueHandling
设置设置不同的行为:在反序列化客户端 json 时忽略不可为 null 的字段的 null 错误,但在序列化结果时为定义的模型字段保留 null。
比如我有一个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" }
.
我需要实现 "Ignore" 输入场景和 "Include" 输出场景。
我会使用 Newtonsoft.Json 中的 JsonSerializerSettings class 来定义两个实例 mySerializeSetting
和 myDeserializeSettings
。
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
终于找到了解决方法: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>());
在服务提供商配置中
ASP.Net Core 2.2 允许使用 MvcJsonOptions.SerializerSettings
属性 设置序列化器设置。问题是它会影响输入和输出。有没有办法为输入(反序列化)和输出(序列化)提供单独的选项?特别是,我需要为 NullValueHandling
设置设置不同的行为:在反序列化客户端 json 时忽略不可为 null 的字段的 null 错误,但在序列化结果时为定义的模型字段保留 null。
比如我有一个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" }
.
我需要实现 "Ignore" 输入场景和 "Include" 输出场景。
我会使用 Newtonsoft.Json 中的 JsonSerializerSettings class 来定义两个实例 mySerializeSetting
和 myDeserializeSettings
。
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
终于找到了解决方法: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>());
在服务提供商配置中