最后我选择了这个解决方案:我创建了一个BaseController
继承自Microsoft.AspNetCore.Mvc.Controller
. 我从这个BaseController
类继承了我的每个控制器。在这个类中,我重写了Microsoft.AspNetCore.Mvc.Controller.Json
方法:
public class BaseController : Controller
{
private readonly JsonSerializerSettings _jsonSerializerSettings;
public BaseController(IServiceProvider services)
{
IOptions<MvcNewtonsoftJsonOptions> newtonsoftOptions = services.GetService<IOptions<MvcNewtonsoftJsonOptions>>();
_jsonSerializerSettings = newtonsoftOptions.Value.SerializerSettings;
_jsonSerializerSettings.NullValueHandling = NullValueHandling.Include;
}
public override JsonResult Json(object data)
{
return Json(data, _jsonSerializerSettings);
}
感谢IOptions<MvcNewtonsoftJsonOptions>
我能够恢复在启动时初始化的序列化程序设置。
编辑
我注意到值的_jsonSerializerSettings.NullValueHandling = NullValueHandling.Include;
变化也会改变初始化序列化程序的设置。所以我做了一个扩展方法来复制序列化程序设置的所有数据,目的是更新新设置:
public CustomerAccountController(IServiceProvider services)
{
IOptions<MvcNewtonsoftJsonOptions> newtonsoftOptions = services.GetService<IOptions<MvcNewtonsoftJsonOptions>>();
_jsonSerializerSettings = newtonsoftOptions.Value.SerializerSettings.CloneJsonSerializerSettings();
_jsonSerializerSettings.NullValueHandling = NullValueHandling.Include;
}
public static JsonSerializerSettings CloneJsonSerializerSettings(this JsonSerializerSettings settings)
{
JsonSerializerSettings cloneSettings = new JsonSerializerSettings();
cloneSettings.StringEscapeHandling = settings.StringEscapeHandling;
cloneSettings.FloatParseHandling = settings.FloatParseHandling;
cloneSettings.FloatFormatHandling = settings.FloatFormatHandling;
cloneSettings.DateParseHandling = settings.DateParseHandling;
cloneSettings.DateTimeZoneHandling = settings.DateTimeZoneHandling;
cloneSettings.DateFormatHandling = settings.DateFormatHandling;
cloneSettings.Formatting = settings.Formatting;
cloneSettings.MaxDepth = settings.MaxDepth;
cloneSettings.DateFormatString = settings.DateFormatString;
cloneSettings.Context = settings.Context;
cloneSettings.Error = settings.Error;
cloneSettings.SerializationBinder = settings.SerializationBinder;
cloneSettings.Binder = settings.Binder;
cloneSettings.TraceWriter = settings.TraceWriter;
cloneSettings.Culture = settings.Culture;
cloneSettings.ReferenceResolverProvider = settings.ReferenceResolverProvider;
cloneSettings.EqualityComparer = settings.EqualityComparer;
cloneSettings.ContractResolver = settings.ContractResolver;
cloneSettings.ConstructorHandling = settings.ConstructorHandling;
cloneSettings.TypeNameAssemblyFormatHandling = settings.TypeNameAssemblyFormatHandling;
cloneSettings.TypeNameAssemblyFormat = settings.TypeNameAssemblyFormat;
cloneSettings.MetadataPropertyHandling = settings.MetadataPropertyHandling;
cloneSettings.TypeNameHandling = settings.TypeNameHandling;
cloneSettings.PreserveReferencesHandling = settings.PreserveReferencesHandling;
cloneSettings.Converters = settings.Converters;
cloneSettings.DefaultValueHandling = settings.DefaultValueHandling;
cloneSettings.NullValueHandling = settings.NullValueHandling;
cloneSettings.ObjectCreationHandling = settings.ObjectCreationHandling;
cloneSettings.MissingMemberHandling = settings.MissingMemberHandling;
cloneSettings.ReferenceLoopHandling = settings.ReferenceLoopHandling;
cloneSettings.ReferenceResolver = settings.ReferenceResolver;
cloneSettings.CheckAdditionalContent = settings.CheckAdditionalContent;
return cloneSettings;
}