dotnet/runtime

Unable to deserialize JSON into a collection property without a getter (with a misleading error message)

Open

#104.700 aperta il 10 lug 2024

Vedi su GitHub
 (8 commenti) (0 reazioni) (0 assegnatari)C# (5445 fork)batch import
area-System.Text.Jsonbughelp wanted

Metriche repository

Star
 (17.886 star)
Metriche merge PR
 (Merge medio 12g 11h) (661 PR mergiate in 30 g)

Descrizione

Description

When trying to deserialize a JSON string into a class containing a property with a collection type (Dictionary or IEnumerable) serializer throws an exception which says about a property missing a setter despite it being present.

Reproduction Steps

JsonSerializer.Deserialize<Test>("{\"Data\":[1]}");

public class Test
{
    [JsonRequired]
    public List<int> Data
    {
        set => FirstValue = value[0];
    }
    
    [JsonIgnore]
    public int FirstValue { get; private set; }
}

Expected behavior

JSON is deserialized correctly.

Actual behavior

The following exception is thrown:

System.InvalidOperationException: JsonPropertyInfo 'Data' defined in type 'Test' is marked required but does not specify a setter.
   at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_JsonPropertyRequiredAndNotDeserializable(JsonPropertyInfo jsonPropertyInfo)
   at System.Text.Json.Serialization.Metadata.JsonPropertyInfo.Configure()
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.ConfigureProperties()
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.Configure()
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.<EnsureConfigured>g__ConfigureSynchronized|172_0()
   at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type type, Boolean ensureConfigured, Nullable`1 ensureNotNull, Boolean resolveIfMutable, Boolean fallBackToNearestAncestorType)
   at Program.<Main>$(String[] args)

Regression?

No, this behavior is present at least since .NET 7 when required properties were introduced.

Known Workarounds

Adding a getter to the property, it is allowed for it to return null or just outright to throw an exception.

Configuration

.NET 8.0.6 running on macOS 14.5 ARM64; issue is not specific to the configuration.

Other information

Similar to (although different scenario): https://github.com/dotnet/runtime/issues/92330

Guida contributor