-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot deserialize an immutable collection #67361
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsDescriptionI'm trying to implement a type that is very similar to public readonly struct Block<T> :
IReadOnlyList<T>,
IEquatable<Block<T>>
{
readonly ImmutableArray<T> _arr;
public Block(IEnumerable<T> elems) => _arr = elems.ToImmutableArray();
// etc.
} I'm running an into trying to deserialize an instance of that type: [Fact]
void Test()
{
var original = Block.Create(1, 2, 3);
var serialized = JsonSerializer.Serialize(original);
var deserialized = JsonSerializer.Deserialize<Block<int>>(serialized); // <-- exception here
Assert.Equal(original, deserialized);
}
/*
Message:
System.NotSupportedException : The collection type 'ValueCollections.Block`1[System.Int32]' is abstract, an interface, or is read only, and could not be instantiated and populated. Path: $ | LineNumber: 0 | BytePositionInLine: 1.
---- System.NotSupportedException : The collection type 'ValueCollections.Block`1[System.Int32]' is abstract, an interface, or is read only, and could not be instantiated and populated.
Stack Trace:
ThrowHelper.ThrowNotSupportedException(ReadStack& state, Utf8JsonReader& reader, NotSupportedException ex)
ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type type, Utf8JsonReader& reader, ReadStack& state)
ICollectionOfTConverter`2.CreateCollection(Utf8JsonReader& reader, ReadStack& state, JsonSerializerOptions options)
JsonCollectionConverter`2.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TCollection& value)
JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo jsonTypeInfo, Nullable`1 actualByteCount)
JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo jsonTypeInfo)
JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
JsonSerializationTests.Try() line 19
*/ The exact same test works perfectly fine with I found that when deserializing I finally tried adding a [JsonConstructor] attribute over the constructor taking an There is support for deserializing immutable types, but this just does not seem to encompass collections. Am I missing anything or the support for this is simply not there? Reproduction StepsYou can use this nuget https://www.nuget.org/packages/ValueCollections.Block/0.0.1-alpha and just try to serialize and deserialize a value of the type, eg: var original = Block.Create(1, 2, 3);
var serialized = JsonSerializer.Serialize(original);
var deserialized = JsonSerializer.Deserialize<Block<int>>(serialized); Expected behaviorIt should be possible to deserialize an immutable collection type. Actual behaviorIt's not possible to deserialize an immutable collection type unless it is one of the hardcoded ones in System.Collections.Immutable. Regression?No response Known WorkaroundsNo response ConfigurationThe type itself is on .NET Standard 2.0. Other informationNo response
|
@asik you've explicitly marked your type as The error message says that the serializer can't deserialize read-only types. |
Hi @gregsdennis , I wouldn't mind if removing |
Duplicate of #38514. Deserialization for arbitrary collection types is not supported since the serializer cannot know how the type is meant to be created or populated (as the error message suggests). We would consider addressing this via #63791. A quick workaround is to author your own custom converter for the collection type. |
Description
I'm trying to implement a type that is very similar to
System.Collections.Immutable.ImmutableArray
; actually it is based entirely on that type, it only overrides equality. So far it looks like this:I'm running into an issue trying to deserialize an instance of that type:
The exact same test works perfectly fine with
ImmutableArray
. I read that I should implementICollection<T>
(orIList<T>
), so I did, but withIsReadOnly
returning true (my type is immutable). JsonSerializer doesn't like this. ButImmutableArray
also implements it by returning true. So what's going on there?I found that when deserializing
ImmutableArray
, anImmutableEnumerableOfTConverterWithReflection
is created. This appears to govern when this type is created: unfortunately, does so by checking that the type is in "System.Collections.Immutable" and is one of a list of hardcoded types from that assembly. So I'm out of luck.I finally tried adding a [JsonConstructor] attribute over the constructor taking an
IEnumerable<T>
, but no dice. I also tried exposing the underlyingImmutableArray
via a [JsonInclude] property, but that doesn't help, JsonSerializer serializes this as an array, not a json object.There is support for deserializing immutable types, but this just does not seem to encompass collections.
Am I missing anything or the support for this is simply not there?
Reproduction Steps
You can use this nuget https://www.nuget.org/packages/ValueCollections.Block/0.0.1-alpha and just try to serialize and deserialize a value of the type, eg:
Expected behavior
It should be possible to deserialize an immutable collection type.
Actual behavior
It's not possible to deserialize an immutable collection type unless it is one of the hardcoded ones in System.Collections.Immutable.
Regression?
No response
Known Workarounds
No response
Configuration
The type itself is on .NET Standard 2.0.
I was testing serialization from a .NET 6 program on Windows 64-bit, Any CPU.
Other information
No response
The text was updated successfully, but these errors were encountered: