3
votes

I have a .net core 3.1 application. I use the library json.net (newtonsoft) to serialize or deserialize the json . This is the app settings for 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());
        });

I've put this line to ignore null json value on deserialization :

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

But I remark that it ignores also null value for serialization (when use Json method of the class Microsoft.AspNetCore.Mvc.Controller), but I don't want this behavior.

Is there a way to specify differents value of NullValueHandling for serialization and for deserialization ?

1
Thank you, but it seems different with .NetCore 3.1 - Nathan Bruet

1 Answers

1
votes

Finally I opt for this solution: I made a BaseController class which inherits from Microsoft.AspNetCore.Mvc.Controller. I have inherited each of my controllers from this BaseController class. In this class, I override the Microsoft.AspNetCore.Mvc.Controller.Json method :

    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);
        }

Thanks to IOptions<MvcNewtonsoftJsonOptions> I was able to recover the serializer settings initialized in the startup.


EDIT

I remarks that the change of value _jsonSerializerSettings.NullValueHandling = NullValueHandling.Include; change also the init serializer settings. So I've made an extensions method to copy all data of serializer settings in aim to update just the new settings :

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;
}