Background and Motivation
Currently, the default json converters used for objects and collection types are internal to System.Text.Json. The library uses hardcoded conventions to decide what default converters to apply to each type: for instance classes that implement IEnumerable<T> are automatically treated as collections, and classes that implement IAsyncEnumerable<T> can only be handled by the async-only IAsyncEnumerable converter. As of today, System.Text.Json offers no mechanism for users to override this convention, and we have received a number of questions from the community about this issue:
Currently the best available workaround is for users to either reimplement the default converters, or wrap/cast the values into a type that produces the desired serialization contract. At the same time, we offer no mechanism for users to tweak the serialization behaviour of the default converters other than using attribute annotations (to be ameliorated once #63686 has been implemented). Related issues:
Proposal
This story proposes making the default internal converters public, so that users are free to opt in to specific converter strategies for their types. Consider the following example:
public class MyClass : IEnumerable<int>, IAsyncEnumerable<int>
{
}
By default, members of type MyClass are serialized as IAsyncEnumerables. Users can still force IEnumerable semantics if they cast the instance to IEnumerable<int>, however there is currently no way to serialize the type as an object. By exposing the default converter types, we can decorate our type definition with attributes:
[JsonConverter(typeof(JsonObjectConverter))] // serialize as object
// [JsonConverter(typeof(JsonCollectionConverter))] // serialize as collection
// [JsonConverter(typeof(JsonAsyncEnumerableConverter)] // serialize as IAsyncEnumerable
public class MyClass : IEnumerable<int>, IAsyncEnumerable<int>
{
}
Moreover, we should consider exposing parameterization on the converters so that users can configure the contract (for example what #38514 is asking for).
NB we should update the source generator so that relevant JsonPropertyAttribute annotations are recognized and trigger relevant metadata generation, cf. #82001 (comment)
Progress
Background and Motivation
Currently, the default json converters used for objects and collection types are internal to System.Text.Json. The library uses hardcoded conventions to decide what default converters to apply to each type: for instance classes that implement
IEnumerable<T>are automatically treated as collections, and classes that implementIAsyncEnumerable<T>can only be handled by the async-only IAsyncEnumerable converter. As of today, System.Text.Json offers no mechanism for users to override this convention, and we have received a number of questions from the community about this issue:Currently the best available workaround is for users to either reimplement the default converters, or wrap/cast the values into a type that produces the desired serialization contract. At the same time, we offer no mechanism for users to tweak the serialization behaviour of the default converters other than using attribute annotations (to be ameliorated once #63686 has been implemented). Related issues:
Proposal
This story proposes making the default internal converters public, so that users are free to opt in to specific converter strategies for their types. Consider the following example:
By default, members of type
MyClassare serialized as IAsyncEnumerables. Users can still force IEnumerable semantics if they cast the instance toIEnumerable<int>, however there is currently no way to serialize the type as an object. By exposing the default converter types, we can decorate our type definition with attributes:Moreover, we should consider exposing parameterization on the converters so that users can configure the contract (for example what #38514 is asking for).
NB we should update the source generator so that relevant
JsonPropertyAttributeannotations are recognized and trigger relevant metadata generation, cf. #82001 (comment)Progress