Use System.Text.Json source generator with custom JsonConverter
Asked Answered
H

1

8

How are custom JsonConverter<> classes used together with System.Text.Json source generator?

I would like to call JsonSerializer.Deserialize<MyType[]>() that doesn't fallback to a reflection-based implementation and uses a custom MyTypeJsonParser : JsonConverter<MyType>.

EDIT to clarify: Custom converter is implemented for MyType, but json contains an array of MyType objects. So, I would like to create source generated JsonSerializerContext that deserializes an array of MyType objects (MyType[]), using generated code to deserialize an array part and manual converter to deserialize a MyType objects part.

Old code (that doesn't use a source generator) applies a custom converter, by adding it to JsonSerializerOptions.Converters.

However, upon further research I found out that Converters property is missing in JsonSourceGenerationOptionsAttribute. The tables in documentation also state that JsonConverterAttribute and JsonSerializerOptions.Converters are not supported in serialization optimization mode. So, it seems that mixing of custom converters with json source generator is currently (.NET 6) not possible.

The documentation is not clear, whether at least metadata collection source generation mode can use JsonConverterAttribute.

Hushaby answered 17/12, 2021 at 11:56 Comment(5)
Could you clarify a little? How are you applying the converter? 1) Via [JsonConverter(typeof(MyTypeJsonParser))] on a property? 2) [JsonConverter(typeof(MyTypeJsonParser))] on MyType itself? 3) By adding it to JsonSerializerOptions.Converters? Also, converters are used to manually serialize and deserialize a type, so how would you use a converter together with source generation for automatic serialization?Supporting
I'm using option #3 (adding it to JsonSerializerOptions.Converters). Custom converter is only for MyType, but json contains array of MyType objects (so source generation would be used for array deserialization and converter for deserialization of MyType objects). Option #2 together with JsonSerializable(typeof(MyType[])) should work I think.Hushaby
I edited the question to provide more details. Option #2 won't work either. It seems custom converters are not supported together with source generation, which is strange since a custom converter already contains (de)serialization code.Hushaby
According to this learn.microsoft.com/en-us/dotnet/standard/serialization/… you can create a JsonSerializerOptions, add your converter and then use jsonSerializer.Serialize( myType, typeof(MyType), new MyTypeContext(myJsonSerializerOptions));Necessarily
@JuanZamudio It works. Thank you! Would you care posting it as an answer, so I can mark it as accepted?Hushaby
N
5

According to the documentation you can create a JsonSerializerOptions, add your converter and use it in the serialization.

var options = new JsonSerializerOptions
{
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
    WriteIndented = false,
};
options.Converters.Add(new MyConverter());

var myJsonSerializerContext = new MyJsonSerializerContext(options);

You cant share your JsonSerializerOptions with several SerializerContext, another thing it was not clear to me reading the documentation is that you can have one SerializerContext for n types.

So you can have one SerializerContext for all your types initialize and cache it so you can reuse it to avoid allocating more memory.

Necessarily answered 21/1, 2022 at 15:26 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.