Closed
Description
Description
JsonSerializer.Deserialize()
throws a NullReferenceException
when the following conditions are met:
- The type being deserialized has a
required
property - The JSON contains a property name not present in the type being deserialized
- The
JsonTypeInfo
argument is source-generated
Reproduction Steps
- Install the latest build of the .NET SDK (
10.0.100-preview.7.25318.104
at the time of writing) - Create a new console app (
dotnet new console
) - Replace
Program.cs
with the following content:
using System.Text.Json;
using System.Text.Json.Serialization;
// Note the additional "Baz" property
var json = """
{
"Bar": "asdf",
"Baz": "hello"
}
""";
_ = JsonSerializer.Deserialize(json, MyJsonSerializerContext.Default.Foo);
class Foo
{
// Note the use of 'required' here
public required string? Bar { get; set; }
}
[JsonSerializable(typeof(Foo))]
partial class MyJsonSerializerContext : JsonSerializerContext;
- Observe that a
NullReferenceException
gets thrown in the call toJsonSerializer.Deserialize()
.
Expected behavior
No exception gets thrown.
Actual behavior
A NullReferenceException
gets thrown.
Regression?
This seems to have regressed in version 10.0.0-preview.6.25314.101
of Microsoft.NETCore.App
.
I was unable to reproduce the issue in version 10.0.0-preview.6.25302.104
.
Known Workarounds
None of these are ideal, but:
- Use
[JsonRequired]
for required properties instead of making themrequired
- Don't use the JSON source generator
- Sanitize the JSON to not include extra properties
Configuration
.NET SDK: 10.0.100-preview.7.25318.104
OS: Windows 11 Enterprise Build 26100.4349
Architecture: x64
I don't believe the issue is specific to this configuration, but I haven't verified this.
Other information
The line throwing the exception is:
(propertyInfo.Options
is null
)
The full stack trace is:
System.Text.Json.dll!System.Text.Json.ReadStackFrame.MarkPropertyAsRead(System.Text.Json.Serialization.Metadata.JsonPropertyInfo propertyInfo) Line 135
at /_/src/runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStackFrame.cs(135)
System.Text.Json.dll!System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter<Foo>.TryLookupConstructorParameter(System.ReadOnlySpan<byte> unescapedPropertyName, ref System.Text.Json.ReadStack state, System.Text.Json.JsonSerializerOptions options, out System.Text.Json.Serialization.Metadata.JsonPropertyInfo jsonPropertyInfo, out System.Text.Json.Serialization.Metadata.JsonParameterInfo jsonParameterInfo) Line 634
at /_/src/runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs(634)
System.Text.Json.dll!System.Text.Json.Serialization.Converters.ObjectWithParameterizedConstructorConverter<Foo>.OnTryRead(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options, ref System.Text.Json.ReadStack state, out Foo value) Line 59
at /_/src/runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs(59)
System.Text.Json.dll!System.Text.Json.Serialization.JsonConverter<System.__Canon>.TryRead(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options, ref System.Text.Json.ReadStack state, out System.__Canon value, out bool isPopulatedValue) Line 253
at /_/src/runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs(253)
System.Text.Json.dll!System.Text.Json.Serialization.JsonConverter<Foo>.ReadCore(ref System.Text.Json.Utf8JsonReader reader, out Foo value, System.Text.Json.JsonSerializerOptions options, ref System.Text.Json.ReadStack state) Line 40
at /_/src/runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.ReadCore.cs(40)
System.Text.Json.dll!System.Text.Json.Serialization.Metadata.JsonTypeInfo<System.__Canon>.Deserialize(ref System.Text.Json.Utf8JsonReader reader, ref System.Text.Json.ReadStack state) Line 22
at /_/src/runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.ReadHelper.cs(22)
System.Text.Json.dll!System.Text.Json.JsonSerializer.ReadFromSpan<System.__Canon>(System.ReadOnlySpan<byte> utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo<System.__Canon> jsonTypeInfo, int? actualByteCount) Line 145
at /_/src/runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs(145)
System.Text.Json.dll!System.Text.Json.JsonSerializer.ReadFromSpan<Foo>(System.ReadOnlySpan<char> json, System.Text.Json.Serialization.Metadata.JsonTypeInfo<Foo> jsonTypeInfo) Line 400
at /_/src/runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs(400)
System.Text.Json.dll!System.Text.Json.JsonSerializer.Deserialize<Foo>(string json, System.Text.Json.Serialization.Metadata.JsonTypeInfo<Foo> jsonTypeInfo) Line 197
at /_/src/runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs(197)
The regression seems to have been introduced in #115856