C# - How to override null value in JsonConvert.SerializeObject output

45 Views Asked by At

I am trying to override the serialized value of a nullable object property using a JsonConverterAttribute pointing to a Custom JsonConverter

In the example shown below I am able to properly override the serialized value of a non-nullable primitive type (MyInt). However, the MyConverter.WriteJson method does not seem to get called when the property is nullable and not initialized (OptInt)

namespace Project
{
    using System;
    using Newtonsoft.Json;

    public class MyConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType) => true;

        public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
        {
            writer.WriteValue(123);
        }

        public override bool CanRead => false;

        public override object? ReadJson(JsonReader reader, Type type, object? value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }

    public class MyModel
    {
        public int Int { get; set; }

        [JsonConverter(typeof(MyConverter))]
        public int MyInt { get; set; }

        [JsonConverter(typeof(MyConverter))]
        [JsonProperty("OptInt", NullValueHandling = NullValueHandling.Ignore)]
        public int? OptInt { get; set; }
    }
}


    [Fact]
    public void TestOptIntSet()
    {
        var myObject = new MyModel(){OptInt = 666};
        var json = JsonConvert.SerializeObject(myObject);
        Assert.Equal("{\"Int\":0,\"MyInt\":123,\"OptInt\":123}", json);

        // Passed

    }

    [Fact]
    public void TestEmptyModel()
    {
        var myObject = new MyModel();
        var json = JsonConvert.SerializeObject(myObject);
        Assert.Equal("{\"Int\":0,\"MyInt\":123,\"OptInt\":123}", json);
        
        // Assert.Equal() Failure
        //                                  ↓ (pos 30)
        // Expected: ···MyInt":123,"OptInt":123}
        // Actual:   ···MyInt":123,"OptInt":null}
        //                                  ↑ (pos 30)
    }

How can I override the null value in the serialized output for a specific nullable property when it is not set ?

Note: NullValueHandling is set to Include by default, setting [JsonProperty("OptInt", NullValueHandling = NullValueHandling.Ignore)] would simply omit OptInt in the serialized output:

        // Assert.Equal() Failure
        //                        ↓ (pos 20)
        // Expected: ···MyInt":123,"OptInt":123}
        // Actual:   ···MyInt":123}
        //                        ↑ (pos 20)
0

There are 0 best solutions below