Skip to content

[Breaking change]: Nullable JsonDocument properties deserialize to JsonValueKind.Null instead of null #43869

@jeffhandley

Description

@jeffhandley

Description

Starting with .NET 9 (Preview 1), deserializing null JSON values into JsonDocument results in non-null documents of JsonValueKind.Null instead of null.

using System.Text.Json;

var doc = JsonSerializer.Deserialize<JsonDocument>("null");

//Returns true in .NET 8 and false in .NET 9
Console.WriteLine(doc is null);

//Returns false in .NET 8 and true in .NET 9
Console.WriteLine(doc is { RootElement.ValueKind: JsonValueKind.Null });

Version

.NET 9 GA

Previous behavior

With .NET 8 and earlier, deserializing null JSON values into JsonDocument gives back null results.

New behavior

With .NET 9 and newer, deserializing null JSON values into JsonDocument gives back non-null instances of JsonValueKind.Null.

Type of breaking change

  • Binary incompatible: Existing binaries might encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
  • Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code might require source changes to compile successfully.
  • Behavioral change: Existing binaries might behave differently at run time.

Reason for change

This change addresses an inconsistency between root-level JSON nulls and nested nulls in a document. It also makes it consistent with the behavior of the JsonDocument.Parse methods. The behavior of returning null was considered a bug and updated for alignment with the expected result.

Issue: JsonDocument JsonSerializer.Deserialize does not match JsonDocument.Parse for null root elements (dotnet/runtime#97323)
PR: handle null value when deserializing JsonDocument (dotnet/runtime#97596)

Recommended action

Update code that consumes deserialized objects containing JsonDocument types to expect JsonValueKind.Null instead of null.

Feature area

Core .NET libraries

Affected APIs


Associated WorkItem - 351646

Metadata

Metadata

Assignees

Labels

📌 seQUESTeredIdentifies that an issue has been imported into Quest.breaking-changeIndicates a .NET Core breaking changein-prThis issue will be closed (fixed) by an active pull request.

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions