dotnet/runtime

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

Open

#104 700 ouverte le 10 juil. 2024

Voir sur GitHub
 (8 commentaires) (0 réactions) (0 assignés)C# (5 445 forks)batch import
area-System.Text.Jsonbughelp wanted

Métriques du dépôt

Stars
 (17 886 stars)
Métriques de merge PR
 (Merge moyen 12j 11h) (661 PRs mergées en 30 j)

Description

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

Guide contributeur