Skip to content

JsonSerializer throws when serializing null value in a value-type nullable union case #128688

Description

@DeagleGross

Description

I've tried union as return type in aspnetcore

public union NullableCaseUnion(int?, string);

app.MapGet("/null",   () => new NullableCaseUnion((int?)null));

and got the following serialization error (full stacktrace below):

System.Text.Json.JsonException : The JSON value could not be converted to System.Int32. Path: $.

I think JsonUnionConverter<TUnion>.OnTryWrite misses a check for caseValue being null in case of valueType. Read side of the converter works well, since it short-curcuits the return checking the tokenType:

if (reader.TokenType is JsonTokenType.Null) {
    Type? nullableCaseType = typeInfo.UnionNullableCaseType;
    value = constructor(nullableCaseType, null);
    return true;
}

Reproduction Steps

string json = await Serializer.SerializeWrapper<ValueTypeNullablePairUnion>(new ValueTypeNullablePairUnion((int?)null));
            ValueTypeNullablePairUnion roundTripped = await Serializer.DeserializeWrapper<ValueTypeNullablePairUnion>(json);
            Assert.Null(roundTripped.Value);

Expected behavior

Serialization rountrip on union union ValueTypeNullablePairUnion(int, int?) works without exception

Actual behavior

throws System.Text.Json.JsonException : The JSON value could not be converted to System.Int32. Path: $.

Serialization error stacktrace
System.Text.Json.JsonException : The JSON value could not be converted to System.Int32. Path: $.

   at System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType)
        ThrowHelper.Serialization.cs:line 52
   at System.Text.Json.JsonSerializer.UnboxOnWrite[T](Object value)
        JsonSerializer.Helpers.cs:line 139
   at System.Text.Json.Serialization.JsonConverter`1.TryWriteAsObject(
            Utf8JsonWriter writer, Object value, JsonSerializerOptions options, WriteStack& state)
        JsonConverterOfT.cs:line 112
   at System.Text.Json.Serialization.Converters.JsonUnionConverter`1.OnTryWrite(
            Utf8JsonWriter writer, TUnion value, JsonSerializerOptions options, WriteStack& state)
        JsonUnionConverter.cs:line 195                         ← bug origin
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(
            Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
        JsonConverterOfT.cs:line 425
   at System.Text.Json.Serialization.JsonConverter`1.WriteCore(
            Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
        JsonConverterOfT.WriteCore.cs:line 48
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.Serialize(
            Utf8JsonWriter writer, T& rootValue, Object rootValueBoxed)
        JsonTypeInfoOfT.WriteHelpers.cs:line 56
   at System.Text.Json.JsonSerializer.WriteString[TValue](TValue& value, JsonTypeInfo`1 jsonTypeInfo)
        JsonSerializer.Write.String.cs:line 154
   at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options)
        JsonSerializer.Write.String.cs:line 33
   at System.Text.Json.Serialization.Tests.JsonSerializerWrapper.StringSerializerWrapper.SerializeWrapper[T](
            T value, JsonSerializerOptions options)
        JsonSerializerWrapper.Reflection.cs:line 119
   at System.Text.Json.Serialization.Tests.UnionTests
            .<UnionWithValueTypeNullableCase_SerializesNullAsJsonNull>d__53.MoveNext()
        UnionTests.cs:line 571
   --- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

Related #127299

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions