Skip to content

NullReferenceException when deserializing object containing nullable struct using source generator #86483

Closed
@wt-brett

Description

@wt-brett

Description

Calling JsonSerializer.Deserialize for an object containing a nullable struct property will throw a NullReferenceException when passing JsonTypeInfo.

Reproduction Steps

  1. Create a new Console App Project.
  2. Use the following code:
using System.Text.Json;
using System.Text.Json.Serialization;

var obj = new MyObj { MyStruct = new MyStruct { Property1 = 2 } };
var json = JsonSerializer.Serialize(obj, SerializerContext.Default.MyObj);
var result = JsonSerializer.Deserialize(json, SerializerContext.Default.MyObj);

public record class MyObj
{
    public MyStruct? MyStruct { get; init; }
}

public struct MyStruct
{
    public byte Property1 { get; init; }
}

[JsonSerializable(typeof(MyObj))]  
internal partial class SerializerContext : JsonSerializerContext
{
}

A NullReferenceException will be thrown on the var result = JsonSerializer.Deserialize(json, SerializerContext.Default.MyObj); line

Expected behavior

Calling JsonSerializer.Deserialize method does not throw NullReferenceException

Actual behavior

Exception Message:
Object reference not set to an instance of an object.

Stack Trace:

at System.Text.Json.Serialization.Converters.LargeObjectWithParameterizedConstructorConverter`1.InitializeConstructorArgumentCaches(ReadStack& state, JsonSerializerOptions options)
 at System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1.BeginRead(ReadStack& state, JsonSerializerOptions options)
 at System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1.ReadConstructorArguments(ReadStack& state, Utf8JsonReader& reader, JsonSerializerOptions options)
 at System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
 at System.Text.Json.Serialization.Converters.JsonMetadataServicesConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
 at System.Text.Json.Serialization.Converters.NullableConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, Nullable`1& value)
 at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
 at System.Text.Json.Serialization.JsonConverter`1.TryReadAsObject(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, Object& value)
 at System.Text.Json.Serialization.Converters.LargeObjectWithParameterizedConstructorConverter`1.ReadAndCacheConstructorArgument(ReadStack& state, Utf8JsonReader& reader, JsonParameterInfo jsonParameterInfo)
 at System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1.ReadConstructorArguments(ReadStack& state, Utf8JsonReader& reader, JsonSerializerOptions options)
 at System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
 at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
 at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
 at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo`1 jsonTypeInfo, Nullable`1 actualByteCount)
 at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo`1 jsonTypeInfo)
 at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonTypeInfo`1 jsonTypeInfo)
 at Program.<Main>$(String[] args)

Regression?

Yes. This code worked correctly in .net 8 preview 3

Known Workarounds

Call var result = JsonSerializer.Deserialize<MyObj>(json); without using the JsonTypeInfo

Configuration

  • Which version of .NET is the code running on?
    .net 8 preview 4

  • What OS and version, and what distro if applicable?
    Windows 11

  • What is the architecture (x64, x86, ARM, ARM64)?
    x64

  • Do you know whether it is specific to that configuration?
    Not sure

Other information

No response

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions