-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove implicit fallback to reflection-based serialization in System.Text.Json sourcegen #71714
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsConsider the following source gen example in .NET 6: JsonSerializer.Serialize(new Poco2(), typeof(Poco2), MyContext.Default);
[JsonSerializable(typeof(Poco1))]
public partial class MyContext : JsonSerializerContext {}
public class Poco1 { }
public class Poco2 { } Since
Note however that if we try to serialize the same type using the JsonSerializer.Serialize(new Poco2(), MyContext.Default.Options); The options instance will silently incorporate the default reflection-based contract resovler as a fallback mechanism, and as such the above will serialize successfully -- using reflection. We believe that this behavior violates the principle of least surprise and ultimately defeats the purpose of source generation. With the release of #63686 users will have the ability to fine tune the sources of their contract metadata -- as such silently introducing alternative sources becomes even less desirable. This issue proposes that we remove the fallback-to-reflection behavior. Namely the call JsonSerializer.Serialize(new Poco2(), MyContext.Default.Options); Should fail with the same exception as using the We acknowledge that certain users might depend on the current behavior, either intentionally or unintentionally. As such, we propose the following workaround using the APIs released in #63686: var options = new JsonSerializerOptions
{
TypeInfoResolver = JsonTypeInfoResolver.Combine(MyContext.Default, new DefaultJsonTypeInfoResolver());
}
JsonSerializer.Serialize(new Poco2(), options); // contract resolution falls back to the default reflection-based resolver. cc @krwq @layomia @jeffhandley @ericstj
|
…t#71714 Include JsonSerializerContext in JsonSerializerOptions copy constructor. Fix dotnet#71716 Move reflection-based converter resolution out of JsonSerializerOptions. Fix dotnet#68878
* Remove implicit fallback to reflection-based serialization. Fix #71714 Include JsonSerializerContext in JsonSerializerOptions copy constructor. Fix #71716 Move reflection-based converter resolution out of JsonSerializerOptions. Fix #68878 * Address feedback & add one more test * Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerContext.cs Co-authored-by: Stephen Toub <stoub@microsoft.com> * fix build * Bring back throwing behavior in JsonSerializerContext and add tests * Only create caching contexts if a resolver is populated * Add null test for JsonSerializerContext interface implementation. * skip RemoteExecutor test in netfx targets * Add DefaultJsonTypeInfoResolver test for types with JsonConverterAttribute * remove nullability annotation * Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs Co-authored-by: Krzysztof Wicher <mordotymoja@gmail.com> Co-authored-by: Stephen Toub <stoub@microsoft.com> Co-authored-by: Krzysztof Wicher <mordotymoja@gmail.com>
Consider the following source gen example in .NET 6:
Since
MyContext
does not includePoco2
in its serializable types, the above will fail with the following exception:Note however that if we try to serialize the same type using the
JsonSerializerOptions
instance constructed by the source generator:The options instance will silently incorporate the default reflection-based contract resolver as a fallback mechanism, and as such the above will serialize successfully -- using reflection.
We believe that this behavior violates the principle of least surprise and ultimately defeats the purpose of source generation. With the release of #63686 users will have the ability to fine tune the sources of their contract metadata -- as such silently introducing alternative sources becomes even less desirable.
This issue proposes that we remove the fallback-to-reflection behavior. Namely the call
Should fail with the same exception as using the
JsonSerializerContext
overload.The same fallback logic applies to
JsonSerializerOptions.GetConverter
for options instances attached to aJsonSerializerContext
. The following statementwill return a converter using the built-in reflection converter. In .NET 7 this will start failing with
NotSupportedException
.We acknowledge that certain users might depend on the current behavior, either intentionally or unintentionally. As such, we propose the following workaround using the APIs released in #63686:
cc @krwq @layomia @jeffhandley @ericstj
The text was updated successfully, but these errors were encountered: