Reputation: 3027
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,
};
Upvotes: 1
Views: 241
Reputation: 117105
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);
Upvotes: 0
Reputation: 143098
As far as I can see you can't specify reference handler on the context but you can pass the context to the options used for deserialization:
var serializerOptions = new JsonSerializerOptions
{
TypeInfoResolver = SourceGenerationContext.Default,
ReferenceHandler = ReferenceHandler.IgnoreCycles
};
var jsonString = JsonSerializer.Serialize(fore, serializerOptions);
See also the Source-generation support in ASP.NET Core section of the docs.
JIC full sample app (with <JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault>
setting):
using System.Text.Json;
using System.Text.Json.Serialization;
Console.WriteLine("Hello, World!");
var forecast = new WeatherForecast();
var myc = new MyClass
{
Forecast = forecast
};
forecast.MyClass = myc;
var serializerOptions = new JsonSerializerOptions
{
TypeInfoResolver = SourceGenerationContext.Default,
ReferenceHandler = ReferenceHandler.IgnoreCycles
};
var jsonString = JsonSerializer.Serialize(forecast, serializerOptions);
Console.WriteLine(jsonString);
[JsonSerializable(typeof(WeatherForecast))]
internal partial class SourceGenerationContext : JsonSerializerContext
{
}
public class WeatherForecast
{
public int Type { get; set; }
public MyClass MyClass { get; set; }
}
public class MyClass
{
public WeatherForecast Forecast { get; set; }
}
Upvotes: 0
Reputation: 1
You’re right that JsonSourceGenerationOptions doesn’t directly support setting the ReferenceHandler. However, you can achieve this by customizing the JsonSerializerOptions in your context. Here’s a way to do it without running into the CS0102 error:
Create a custom JsonSerializerOptions property in your partial class. Use this property when serializing or deserializing.
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(WeatherForecast))]
internal partial class SourceGenerationContext : JsonSerializerContext
{
private static readonly JsonSerializerOptions _customOptions = new JsonSerializerOptions
{
ReferenceHandler = ReferenceHandler.IgnoreCycles,
WriteIndented = true
};
public static JsonSerializerOptions CustomOptions => _customOptions;
}
Then, when you need to serialize or deserialize, use the CustomOptions.
Upvotes: -1