-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
System.Text.Json Deserialization throws NotSupportedException when implementing IEnumerable<T> #46920
Comments
Like it says: Not supported. Track #45189 |
@Symbai I think this is a different scenario. The exception says NotSupportedException because the type is abstract, an interface, or is read only. The |
This isn't the polymorphic case if you uses |
@Symbai , with the model type I can implement other interfaces, and this does not give any problem with deserialization. |
I ran into the very same problem. Deserializing to the concrete type throws an exception simply because that type implements IEnumerable. It seems the deserializer checks if the type implements the interface at all even when it shouldn't matter. Removing the interface worked, but was not what I wanted (for similar reasons to the above). |
actually, it looks like the serialization is also wrong here.
|
@wzchua, yes, you're right - serialization is also wrong. Card and Category types which implement IEnumerable are not correctly serialized, although there's no exception on serialization. The current status:
|
I'm not sure how this can be handled besides a custom converter. |
@wzchua, thanks for this information. Creating a custom converter that's just using the object converter could be a solution. I'll look into how to create this on using the object converter. Anyway, I think this scenario should result into a feature request:
|
Is this documentation incorrect? I've created a simple class that implements It's a bit frustrating that all of the |
Thanks for the information and the link @jayoungers - I missed this documentation. The list of types and interfaces here https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-supported-collection-types?pivots=dotnet-5-0#systemcollectionsgeneric-namespace only list the members that are serializable (including With the section on custom collections, Because I'm not thinking about these feature requests:
|
@christiannagel - regarding the My collection class is internal class RecordArrayConverterFactory : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
=> typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(RecordArray<>);
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
=> (JsonConverter)Activator.CreateInstance(typeof(RecordArrayConverter<>).MakeGenericType(typeToConvert.GetGenericArguments()[0]));
private class RecordArrayConverter<T> : JsonConverter<RecordArray<T>>
{
public override RecordArray<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> new RecordArray<T>(((JsonConverter<T[]>)options.GetConverter(typeof(T[]))).Read(ref reader, typeof(T[]), options));
public override void Write(Utf8JsonWriter writer, RecordArray<T> value, JsonSerializerOptions options)
=> ((JsonConverter<IEnumerable<T>>)options.GetConverter(typeof(IEnumerable<T>))).Write(writer, value, options);
}
} |
There are 2 use cases for a class implementing a collection interface:
These use cases are not mutually exclusive - a class could desire collection semantics in addition to object semantics. This is the currently unsupported case mentioned in docs#22402. The lack of support for these "families" of classes makes for some very cumbersome hacks (custom converters etc.) for otherwise very powerful and expressive .NET data types. |
@christiannagel - the serializer treats all types that are assignable to There is a feature request to do just this: #1808. One solution is to provide a new attribute, say |
This issue has been automatically marked |
JsonSerializer.Deserialize
throwsNotSupportedException
whenIEnumerable<T>
is implemented.The
Category
andCard
records implement the interfaceIEnumerable<T>
:This allows creating objects with an collection initializer:
Using a Card object, serialization with the JsonSerializer succeeds. Deserialization throws the NotSupportedException because the type is abstract, an interface, or is read only which is not the case.
Call stack:
If the implementation of the
IEnumerable<T>
interface is removed, and all other code stays the same, deserialization works as expected. The issue only occurs if the interface is implemented. Without this interface, the collection initializer cannot be used.Sample project is available here: https://github.com/christiannagel/jsonserializerwithienumerable
Thanks!
The text was updated successfully, but these errors were encountered: