Search code examples
c#.netserializationsystem.text.jsonsourcegenerators

Default serialization option for reference handler while setting up JsonSerializerContext


I'd like to set the default serialization option for reference handler to ignore cycles. I noticed JsonSourceGenerationOptions does not have a property for reference handler unlike JsonSerializerOptions. How is it possible to do this with JsonSourceGenerationOptions while creating a context?

[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(WeatherForecast))]
internal partial class SourceGenerationContext : JsonSerializerContext
{
}

Alternatively, is there another way to override the default options? I tried overriding GeneratedSerializerOptions but received CS0102: The type already contains a definition for 'GeneratedSerializerOptions' error.

protected override JsonSerializerOptions GeneratedSerializerOptions => new JsonSerializerOptions
{
    ReferenceHandler = ReferenceHandler.IgnoreCycles,
};

Solution

  • In this comment to [API Proposal]: JsonSourceGenerationOptions should support ReferenceHandler #107597, Eirik Tsarpalis of MSFT gives a workaround, which is to pass JsonSerializerOptions with the required ReferenceHandler value into the JsonSerializerContext(JsonSerializerOptions) constructor that is automatically generated for your source generation context, then assign the result to a custom static instance like so:

    [JsonSourceGenerationOptions(WriteIndented = true)]
    [JsonSerializable(typeof(WeatherForecast))]
    internal partial class SourceGenerationContext : JsonSerializerContext
    {
        public static SourceGenerationContext IgnoreCycles { get; } = new(new JsonSerializerOptions 
        { 
            ReferenceHandler = ReferenceHandler.IgnoreCycles,
            WriteIndented = true,
        });
    }
    

    Once you have the required static instance, you can use it when serializing e.g. like so:

    var forecast = new WeatherForecast { /* Initialize with possibly cyclic property values */ };
    var json = JsonSerializer.Serialize(forecast, 
                                        SourceGenerationContext.IgnoreCycles.WeatherForecast);