Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement System.Text.Json source generator with a generic class?

I have a generic class like this:

public class Property<TObjectType>
{
}

I would like to use the new System.Text.Json source generator but it does not seem to work for a generic class. Here is the derived JsonSerializerContext for that class:

[JsonSerializable(typeof(Property<>))]
public partial class PropertyJsonContext<TObjectType> : JsonSerializerContext
{
}

The error is a bit weird as it makes all the other non-generic JsonSerializerContext implementations fail with these 2 errors:

Error CS0534: 'XXXJsonContext' does not implement inherited abstract member 'JsonSerializerContext.GeneratedSerializerOptions.get'

Error CS0534: 'XXXJsonContext' does not implement inherited abstract member 'JsonSerializerContext.GetTypeInfo(Type)'

There is also this warning that I feel is related to my problem:

CSC : warning CS8785: Generator 'JsonSourceGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type 'ArgumentException' with message 'The hintName 'PropertyJsonContext`1.NSPropertyTObjectType.g.cs' contains an invalid character '`' at position 21.

Then I changed the derived class to remove the genericity:

[JsonSerializable(typeof(NSProperty<>))]
public partial class NSPropertyJsonContext : JsonSerializerContext
{
}

And I get this error:

  The type or namespace name 'TObjectType' could not be found in the global namespace (are you missing an assembly reference?)
like image 633
Kzrystof Avatar asked Aug 16 '26 01:08

Kzrystof


1 Answers

I implemented JSON source code generation today in my application using .net 7. The trick is to specify the possible concrete types and give it a name:

[JsonSerializable(typeof(Property<Foo>), TypeInfoPropertyName = "PropertyOfFoo")]
[JsonSerializable(typeof(Property<Bar>), TypeInfoPropertyName = "PropertyOfBar")]
[JsonSerializable(typeof(Property<IDictionary<string, string>>), TypeInfoPropertyName = "PropertyBag")]
public partial class PropertyJsonContext : JsonSerializerContext
{
}

In case of Bar you can pass PropertyJsonContext.Default.PropertyOfBar to the JsonSerializer methods. I changed my APIs that the caller (which passes chooses a concrete type for TObjectState) also pass in JsonTypeInfo<T>, in the example above that would be JsonTypeInfo<Property<TObjectState>>.

like image 136
koepalex Avatar answered Aug 17 '26 15:08

koepalex



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!