Yes, parsing valid JSON "null" with a JSON serializer have to return null.

WeatherForecast? weatherForecast = 
  JsonSerializer.Deserialize<WeatherForecast>("null");

Note that other valid JSON strings like "123", "\"bob\"", "[]" should cause an exception because none of them represent a valid object.

Answer from Alexei Levenkov on Stack Overflow
🌐
Microsoft Learn
learn.microsoft.com › en-us › dotnet › core › compatibility › serialization › 5.0 › jsonserializer-serialize-throws-argumentnullexception-for-null-type
Breaking change: Serialize throws exception when type parameter is null - .NET | Microsoft Learn
In .NET Core 3.1, the JsonSerializer.Serialize, JsonSerializer.SerializeAsync(Stream, Object, Type, JsonSerializerOptions, CancellationToken), and JsonSerializer.SerializeToUtf8Bytes(Object, Type, JsonSerializerOptions) overloads that have a Type parameter throw an ArgumentNullException when null is passed for the Type inputType parameter, but not if the Object value parameter is also null.
🌐
Reddit
reddit.com › r/dotnet › json serializer should exclude null values in jsonelement
r/dotnet on Reddit: JSON serializer should exclude null values in JsonElement
April 21, 2024 -

i have a list of records with the following definition. basically a IEnumerable<MyComponent>. The MyComponent record has two properties with the type JsonElement. They usually are a Json object with multiple properties of various data types.

Now i want to serialize the IEnumerable<MyComponent> so that all null values in the nested objects of Attributes and Internals are removed. basically the serializer should only return the Json with the attributes which have an explicit value. Unfortunately this seems to be a harder problem than expected.

I tried to use JsonIgnoreCondition.WhenWritingNull but this setting doesn't care about the nested properties inside of Attributes and Internals. Does anyone have good solution for this?

public record MyComponent
{
    public required string Uid { get; init; }
    public JsonElement? Attributes { get; init; }
    public JsonElement? Internals { get; init; }
}

example:

basically this:

[{
  "Uid": 10,
  "Attributes": {
      "a": 10,
      "b": null,
      "c": "test"
  },
  "Internals": {
      "x": "int1",
      "y": ["test", "blub"],
      "z": null
  }
}]

should result in:

[{
  "Uid": 10,
  "Attributes": {
      "a": 10,
      "c": "test"
  },
  "Internals": {
      "x": "int1",
      "y": ["test", "blub"],
  }
}]
🌐
Reddit
reddit.com › r/csharp › serialize object to empty object {} instead of null with system.text.json
r/csharp on Reddit: Serialize object to empty object {} instead of null with System.Text.Json
March 15, 2024 -

Using:

  • .net 8

  • System.Text.Json serializer.

Let's say I have a two classes defined like this:

public class SampleClass
{
    public SampleClassDetail? FirstProperty { get; set; }
    public SampleClassDetail? SecondProperty { get; set; }
}
public class SampleClassDetail
{
    public int MyProperty { get; set; }
}

And an instance of `SampleClass` :

SampleClass sample = new()
{
    FirstProperty = new SampleClassDetail { MyProperty = 1 }
};

Then I want to serialize it with `System.Text.Json`:

string serialized = JsonSerializer.Serialize(sample);

This produces:

{
  "FirstProperty": {
    "MyProperty": 1
  },
  "SecondProperty": null
}

But I would the null to be treated like: `"SecondProperty": {}`

I've tried creating a CustomJson Converter and adding it to the options:

public class SampleClassDetailConverter : JsonConverter<SampleClassDetail?>
{
    public override SampleClassDetail? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }

    public override void Write(Utf8JsonWriter writer, SampleClassDetail? value, JsonSerializerOptions options)
    {
        if (value == null)
        {
            writer.WriteStartObject();
            writer.WriteEndObject();
        }
        else
        {
            var newOptions = new JsonSerializerOptions(options);
            newOptions.Converters.Remove(this);
            JsonSerializer.Serialize(writer, value, newOptions);
        }
    }
}
var options = new JsonSerializerOptions();
options.Converters.Add(new SampleClassDetailConverter());
string serialized = JsonSerializer.Serialize(sample, options);

But still getting the same.

I've created a dotnetfiddle:

https://dotnetfiddle.net/PsXrxt

Any idea how to achieve this?

Top answer
1 of 5
32
What you're asking for doesn't make sense. If they need to be objects in the output JSON, then the properties shouldn't be nullable, and should be initialized by default. something like public class MyClass { public Sample PropertyOne { get; set; } = new(); public Sample PropertyTwo { get; set; } = new(); }
2 of 5
18
You are on the right track but by default, JsonConverter ignores null values. You have to override the HandNull property. Find the section title "Handle null values" from these docs https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/converters-how-to?pivots=dotnet-8-0 Converter Class: public class SampleClassDetailConverter : JsonConverter { public override bool HandleNull => true; public override SampleClassDetail Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { throw new NotImplementedException(); } public override void Write(Utf8JsonWriter writer, SampleClassDetail value, JsonSerializerOptions options) { if (value == null) { writer.WriteStartObject(); writer.WriteEndObject(); } else { JsonSerializer.Serialize(writer, value, value.GetType(), options); } } } Also, I'm not sure if adding the converter to the options like that will work (It could I just can't remember) but I know that annotating the class object will: public class SampleClass { [JsonConverter((typeof(SampleClassDetailConverter)))] public SampleClassDetail? FirstProperty { get; set; } [JsonConverter((typeof(SampleClassDetailConverter)))] public SampleClassDetail? SecondProperty { get; set; } }
🌐
Microsoft Learn
learn.microsoft.com › en-us › dotnet › standard › serialization › system-text-json › ignore-properties
How to ignore properties with System.Text.Json - .NET | Microsoft Learn
Read-only collection-type properties are still serialized even if JsonSerializerOptions.IgnoreReadOnlyProperties is set to true. To ignore all null-value properties, set the DefaultIgnoreCondition property to WhenWritingNull, as shown in the following example:
🌐
Medium
madhawapolkotuwa.medium.com › ignoring-null-values-in-json-serialization-in-c-de6783cc3d3b
Ignoring null Values in JSON Serialization in C# | by Madhawa Polkotuwa | Medium
August 30, 2024 - var orderWithAddress = new OrderResponse { Id = Guid.NewGuid(), Status = OrderStatus.Shipped, DeliveryAddress = new AddressResponse { Street = "123 Main St", City = "Springfield", ZipCode = "12345" } }; var orderWithoutAddress = new OrderResponse { Id = Guid.NewGuid(), Status = OrderStatus.Pending, DeliveryAddress = null // This will be ignored in the JSON output }; ... var options = new JsonSerializerOptions { WriteIndented = true }; string jsonWithAddress = JsonSerializer.Serialize(orderWithAddress, options); string jsonWithoutAddress = JsonSerializer.Serialize(orderWithoutAddress, options); Console.WriteLine("Order with Address:"); Console.WriteLine(jsonWithAddress); Console.WriteLine("\nOrder without Address:"); Console.WriteLine(jsonWithoutAddress);
🌐
Microsoft Learn
learn.microsoft.com › en-us › dotnet › standard › serialization › system-text-json › nullable-annotations
Respect nullable annotations - .NET | Microsoft Learn
November 7, 2025 - The following code snippet throws a JsonException during serialization with a message like: The constructor parameter 'Name' on type 'Person' doesn't allow null values. Consider updating its nullability annotation. public static void RunIt() { #nullable enable JsonSerializerOptions options = new() { RespectNullableAnnotations = true }; string json = """{"Name":null}"""; JsonSerializer.Deserialize<Person>(json, options); } record Person(string Name);
🌐
Newtonsoft
newtonsoft.com › json › help › html › NullValueHandlingIgnore.htm
NullValueHandling setting
Person person = new Person { Name = "Nigal Newborn", Age = 1 }; string jsonIncludeNullValues = JsonConvert.SerializeObject(person, Formatting.Indented); Console.WriteLine(jsonIncludeNullValues); // { // "Name": "Nigal Newborn", // "Age": 1, // "Partner": null, // "Salary": null // } string jsonIgnoreNullValues = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); Console.WriteLine(jsonIgnoreNullValues); // { // "Name": "Nigal Newborn", // "Age": 1 // } Json.NET Home
🌐
GitHub
github.com › dotnet › runtime › issues › 682
System.Text.Json: don't emit null values when serializing collections · Issue #682 · dotnet/runtime
December 9, 2019 - var objects = new Dictionary<string, object> { { "a", "!" }, { "b", 1 }, { "c", null }, { "d", new object() }, { "e", DBNull.Value } }; var json = JsonSerializer.Serialize(objects, new JsonSerializerOptions { IgnoreNullValues = true, WriteIndented = true }); Console.WriteLine(json);
Author: dotnet
Find elsewhere
Top answer
1 of 1
27

Okay, I think I've come up with a solution (my first solution wasn't right at all, but then again I was on the train). You need to create a special contract resolver and a custom ValueProvider for Nullable types. Consider this:

public class NullableValueProvider : IValueProvider
{
    private readonly object _defaultValue;
    private readonly IValueProvider _underlyingValueProvider;


    public NullableValueProvider(MemberInfo memberInfo, Type underlyingType)
    {
        _underlyingValueProvider = new DynamicValueProvider(memberInfo);
        _defaultValue = Activator.CreateInstance(underlyingType);
    }

    public void SetValue(object target, object value)
    {
        _underlyingValueProvider.SetValue(target, value);
    }

    public object GetValue(object target)
    {
        return _underlyingValueProvider.GetValue(target) ?? _defaultValue;
    }
}

public class SpecialContractResolver : DefaultContractResolver
{
    protected override IValueProvider CreateMemberValueProvider(MemberInfo member)
    {
        if(member.MemberType == MemberTypes.Property)
        {
            var pi = (PropertyInfo) member;
            if (pi.PropertyType.IsGenericType && pi.PropertyType.GetGenericTypeDefinition() == typeof (Nullable<>))
            {
                return new NullableValueProvider(member, pi.PropertyType.GetGenericArguments().First());
            }
        }
        else if(member.MemberType == MemberTypes.Field)
        {
            var fi = (FieldInfo) member;
            if(fi.FieldType.IsGenericType && fi.FieldType.GetGenericTypeDefinition() == typeof(Nullable<>))
                return new NullableValueProvider(member, fi.FieldType.GetGenericArguments().First());
        }

        return base.CreateMemberValueProvider(member);
    }
}

Then I tested it using:

class Foo
{
    public int? Int { get; set; }
    public bool? Boolean { get; set; }
    public int? IntField;
}

And the following case:

[TestFixture]
public class Tests
{
    [Test]
    public void Test()
    {
        var foo = new Foo();

        var settings = new JsonSerializerSettings { ContractResolver = new SpecialContractResolver() };

        Assert.AreEqual(
            JsonConvert.SerializeObject(foo, Formatting.None, settings), 
            "{\"IntField\":0,\"Int\":0,\"Boolean\":false}");
    }
}

Hopefully this helps a bit...

Edit – Better identification of the a Nullable<> type

Edit – Added support for fields as well as properties, also piggy-backing on top of the normal DynamicValueProvider to do most of the work, with updated test

🌐
Conrad Akunga
conradakunga.com › blog › handling-null-and-empty-strings-with-system-text-json
Handling Null And Empty Strings With System.Text.Json | Conrad Akunga - Building Software In .NET
March 9, 2021 - This is a special class that we can subclass and override to control the serialization (and deserialization) process of an object. public class NullToEmptyStringConverter : JsonConverter<string> { // Override default null handling public override bool HandleNull => true; // Check the type public ...
🌐
GitHub
github.com › dotnet › runtime › issues › 39152
System.Text.Json: Ignore null values while serializing · Issue #39152 · dotnet/runtime
July 12, 2020 - public class MyClass { public int[] ReferenceType { get; set; } public int ValueType { get; set; } } [Fact] public static void Serialize_value_type_but_not_reference_type() { var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenNull }; string json = @"{""ReferenceType"":null, ""ValueType"":18}"; var obj = JsonSerializer.Deserialize<MyClass>(json, options); // Deserialize Assert.Null(obj.ReferenceType); Assert.Equal(18, obj.ValueType); // Deserialize obj = new MyClass(); json = JsonSerializer.Serialize(obj, options); Assert.Equal(@"{""ValueType"":0}", json); }
Author: dotnet
🌐
Makolyte
makolyte.com › csharp-ignore-null-properties-during-json-serialization
C# - Ignore null properties during JSON serialization | makolyte
January 26, 2025 - To ignore all null properties, set JsonSerializerSettings.NullValueHandling to NullValueHandling.Ignore.
🌐
Microsoft Learn
learn.microsoft.com › en-us › dotnet › api › system.text.json.jsonserializeroptions.ignorenullvalues
JsonSerializerOptions.IgnoreNullValues Property (System.Text.Json) | Microsoft Learn
JsonSerializerOptions.IgnoreNullValues is obsolete. To ignore null values when serializing, set DefaultIgnoreCondition to JsonIgnoreCondition.WhenWritingNull.
🌐
Answer Overflow
answeroverflow.com › m › 1137243638032764988
❔ How to serialize certain null values with System.Text.Json - C#
August 6, 2023 - record Item(string Text, int? Number); List<Item> items = new(); JsonSerializerOptions options = new() { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault, }; string json = JsonSerializer.Serialize(items, options);
🌐
GitHub
github.com › dotnet › docs › issues › 20823
Do not pass null value for parameter `Type inputType` in JsonSerializer.Serialize · Issue #20823 · dotnet/docs
September 29, 2020 - Passing in null for the Type parameter of the JsonSerialaizer.Serialize is unacceptable and should throw ArgumentNullException in that case.
Author: dotnet
🌐
GitHub
github.com › dotnet › runtime › issues › 418
JsonSerializer does not serialize DBNull.Value as null · Issue #418 · dotnet/runtime
December 1, 2019 - using System; using Newtonsoft.Json; public class Program { public static void Main() { Console.WriteLine(JsonConvert.SerializeObject(DBNull.Value)); // null Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(DBNull.Value)); // {} } } cc @RandomGHUser, @SanderSade ·
Author: dotnet
🌐
Conrad Akunga
conradakunga.com › blog › handling-null-and-empty-strings-with-systemtextjson-part-2
Handling Null And Empty Strings With System.Text.Json - Part 2 | Conrad Akunga - Building Software In .NET
November 21, 2022 - value, JsonSerializerOptions options) { if (value == null) writer.WriteStringValue(""); else writer.WriteStringValue(value); } } We finally create an JsonSerializationOptions object to tell the serializer to use our custom converter.