Skip to content

Handle JSON null token when reading collections mapped to JSON#38459

Draft
Copilot wants to merge 5 commits into
mainfrom
copilot/fix-json-null-token-issue
Draft

Handle JSON null token when reading collections mapped to JSON#38459
Copilot wants to merge 5 commits into
mainfrom
copilot/fix-json-null-token-issue

Conversation

Copilot AI commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

A JSON column/property mapped to a primitive collection (e.g. List<string>?) threw InvalidOperationException: Invalid token type: 'Null' when the stored value was a JSON null literal instead of an array.

The three collection reader/writers only accepted a StartArray token at the top level. Nulls are usually short-circuited before reaching the reader (e.g. FromJsonPropertyString), but the value-converter path (CollectionToJsonStringConverter.FromJsonString) and nested JSON documents can drive the reader directly to a Null token.

Changes

  • JsonValueReaderWriter.FromJsonString: short-circuits on a top-level JsonTokenType.Null and returns null — one central place covers all reader/writers without needing per-class handling. Return type updated from object to object? to accurately reflect that null is a valid return value.
  • EFCore.baseline.json: updated FromJsonString signature to object?.
  • Tests: added Can_read_write_null_value_of_collection_of_string_JSON_values, Can_read_write_null_value_of_collection_of_int_JSON_values, and Can_read_write_null_value_of_collection_of_nullable_int_JSON_values to JsonTypesTestBase, asserting that a JSON "null" value round-trips as a null collection while normal arrays still read correctly. The Can_read_and_write_JSON_value helper now also exercises the FromJsonString("null") path for null values.
public object? FromJsonString(string json, object? existingObject = null)
{
    ...
    return readerManager.CurrentReader.TokenType == JsonTokenType.Null
        ? null
        : FromJson(ref readerManager, existingObject);
}

Copilot AI and others added 2 commits June 18, 2026 17:32
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix mapping issue for nullable reference collections in JSON Handle JSON null token when reading collections mapped to JSON Jun 18, 2026
Copilot AI requested a review from AndriySvyryd June 18, 2026 17:36
@AndriySvyryd AndriySvyryd requested a review from Copilot June 19, 2026 01:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes JSON primitive-collection reader/writers so that a top-level JSON null token materializes as a null collection rather than throwing, aligning behavior across direct-reader usage (e.g., value converters) and nested JSON reads.

Changes:

  • Updated JsonCollectionOfReferencesReaderWriter and JsonCollectionOfStructsReaderWriter to return null when the current token is JsonTokenType.Null.
  • Updated JsonCollectionOfNullableStructsReaderWriter to return null when the current token is JsonTokenType.Null (after the existing None advance).
  • Added JsonCollectionReaderWriterTest to assert "null" round-trips to null across reference, struct, and nullable-struct collection reader/writers.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/EFCore/Storage/Json/JsonCollectionOfReferencesReaderWriter.cs Accept top-level Null token and return null rather than throwing.
src/EFCore/Storage/Json/JsonCollectionOfStructsReaderWriter.cs Accept top-level Null token and return null rather than throwing.
src/EFCore/Storage/Json/JsonCollectionOfNullableStructsReaderWriter.cs Accept top-level Null token and return null (with existing None handling).
test/EFCore.Tests/Storage/Json/JsonCollectionReaderWriterTest.cs New unit tests validating "null" reads as null for various collection shapes.

Comment on lines +58 to +61
if (manager.CurrentReader.TokenType == JsonTokenType.Null)
{
return null!;
}
/// <inheritdoc />
public override object FromJsonTyped(ref Utf8JsonReaderManager manager, object? existingObject = null)
{
if (manager.CurrentReader.TokenType == JsonTokenType.Null)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Try find a way to short-circuit this at a different level so that this doesn't need to be handled in each ReaderWriter

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. The null short-circuit is now in JsonValueReaderWriter.FromJsonString — when the token type is JsonTokenType.Null it returns null directly, before calling any per-type FromJson. The return type was also updated from object to object? and the API baseline updated accordingly. The three collection reader/writers no longer need individual null checks.

Commit: 7e0c0b2


namespace Microsoft.EntityFrameworkCore.Storage;

public class JsonCollectionReaderWriterTest

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Add tests to JsonTypesTestBase for these scenarios instead of these unit tests

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. The unit test file has been removed and three new test methods have been added to JsonTypesTestBase: Can_read_write_null_value_of_collection_of_string_JSON_values, Can_read_write_null_value_of_collection_of_int_JSON_values, and Can_read_write_null_value_of_collection_of_nullable_int_JSON_values. The Can_read_and_write_JSON_value helper was also updated to exercise FromJsonString("null") for null values.

Commit: 7e0c0b2

Copilot AI and others added 2 commits June 19, 2026 02:30
…aderWriter

Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants