Различное значение NullValueHandling для сериализации и десериализации

У меня есть приложение .net core 3.1. Я использую библиотеку json.net (newtonsoft) для сериализации или десериализации json. Это настройки приложения для newtonsoft:

        public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers(options =>
        {
            options.SuppressAsyncSuffixInActionNames = false;
        }).AddNewtonsoftJson(options =>
        {
            options.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local;
            options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
            options.SerializerSettings.Converters.Add(new GuidJsonConverter());
        });

Я поместил эту строку, чтобы игнорировать нулевое значение json при десериализации:

options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;

Но я отмечаю, что он также игнорирует нулевое значение для сериализации (при использовании метода Json класса Microsoft.AspNetCore.Mvc.Controller), но я не хочу такого поведения.

Есть ли способ указать разные значения NullValueHandling для сериализации и десериализации?


person Nathan Bruet    schedule 23.07.2020    source источник
comment
Спасибо, но с .NetCore 3.1 все по-другому   -  person Nathan Bruet    schedule 24.07.2020


Ответы (1)


Наконец, я выбрал это решение: я создал класс 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;
}
person Nathan Bruet    schedule 24.07.2020