-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Description
Description
With the release of source generation in .NET 6 the JsonSerializerOptions copy constructor was intentionally made to ignore its JsonSerializerContext state (see also dotnet/aspnetcore#38720). This made sense at the time since JsonSerializerContext was designed to have a 1:1 relationship with JsonSerializerOptions instances. The introduction of dotnet/runtime#63686 generalizes and replaces JsonSerializerContext with IJsonTypeInfoResolver, which removes the need for such tight coupling.
We have updated the copy constructor to include the IJsonTypeInfoResolver/JsonSerializerContext information, which could manifest as a breaking change for certain .NET 6 scenaria.
Version
.NET 7 Preview 7
Previous behavior
In .NET 6, the code
var options = new JsonSerializerOptions(MyContext.Default.Options);
JsonSerializer.Serialize(new Poco2(), options);
[JsonSerializable(typeof(Poco1))]
public partial class MyContext : JsonSerializerContext {}
public class Poco1 {}
public class Poco2 {}serializes successfully since the MyContext configuration (which doesn't support Poco2) is discarded by the copy constructor -- serialization succeeds because the new options instance defaults to using reflection-based serialization.
New behavior
The same code now throws InvalidOperationException, since the copy constructor now incorporates MyContext metadata which does not support Poco2 contracts.
Type of breaking change
- Binary incompatible: Existing binaries may encounter a breaking change in behavior, such as failure to load/execute or different run-time behavior.
- Source incompatible: Source code may encounter a breaking change in behavior when targeting the new runtime/component/SDK, such as compile errors or different run-time behavior.
Reason for change
JsonSerializerContext was the only setting ignored by the copy constructor, which was surprising behavior for certain users.
Recommended action
Users depending on .NET 6 behavior can now manually unset the TypeInfoResolver property to get back reflection-based contract resolution:
var options = new JsonSerializerOptions(MyContext.Default.Options);
options.TypeInfoResolver = null; // unset `MyContext.Default` as the resolver for the options instance.Feature area
Core .NET libraries
Affected APIs
No response