Remove JsonSerializerOptions copy in ProblemDetailsJsonOptionsSetup#46225
Remove JsonSerializerOptions copy in ProblemDetailsJsonOptionsSetup#46225brunolins16 wants to merge 6 commits into
Conversation
| @@ -13,13 +12,8 @@ public void PostConfigure(string? name, JsonOptions options) | |||
| { | |||
| if (options.SerializerOptions.TypeInfoResolver is not null) | |||
There was a problem hiding this comment.
Why are we checking for null?
There was a problem hiding this comment.
I don't think make sense we setup our internal context when the app is configured for reflection-based, and actually this condition might be something like options.SerializerOptions.TypeInfoResolver is not null && if (options.SerializerOptions.TypeInfoResolver is not DefaultTypeInfoResolver or options.SerializerOptions.TypeInfoResolver is JsonSerializerContext
There was a problem hiding this comment.
I feel like it is useless, I believe our context will never be used in this case since it will be added later or even worse, if it was null, now the app might break because we set a context. The only scenario where adding it helps it if, when null, another post-config sets a context.
There was a problem hiding this comment.
Why does the app break if we set a context?
There was a problem hiding this comment.
The summary is, once you add a context, the reflection based one will not be used ever?
There was a problem hiding this comment.
This breaks right:
var options = new JsonSerializerOptions();
options.AddContext<MyContext>();
JsonSerializer.Serialize(new Student("David", 1), options);
record Student(string Name, int Grade);
record Person(string Name);
[JsonSerializable(typeof(Person))]
partial class MyContext : JsonSerializerContext
{
}There was a problem hiding this comment.
The summary is, once you add a context, the reflection based one will not be used ever?
Correct. If the TypeInfoResolver property has been configured, then the serializer will not attempt to populate it with reflection resolution.
There was a problem hiding this comment.
The summary is, once you add a context, the reflection based one will not be used ever?
The only scenario it will not be true is if you set the DefaultTypeInfoResolver first, but in this case your source gen context will not be used. This will work:
var options = new JsonSerializerOptions() { TypeInfoResolver = new DefaultJsonTypeInfoResolver() };
options.AddContext<MyContext>();
JsonSerializer.Serialize(new Student("David", 1), options);
record Student(string Name, int Grade);
record Person(string Name);
[JsonSerializable(typeof(Person))]
partial class MyContext : JsonSerializerContext
{}There was a problem hiding this comment.
Just be make it clear, the call to AddContext append the new context to be executed later.
Since the reflection-based will be able to GetTypeInfo we will never call the source generated context
…ns16/aspnetcore into brunolins16/issues/46143
| public void PostConfigure(string? name, JsonOptions options) | ||
| { | ||
| if (options.SerializerOptions.TypeInfoResolver is not null) | ||
| if (options.SerializerOptions.TypeInfoResolver is not null && options.SerializerOptions.TypeInfoResolver is not DefaultJsonTypeInfoResolver) |
There was a problem hiding this comment.
This isn't making sense to me. Why don't we always want to use this context? Also changes like this that aren't obvious need to big comment 😄
There was a problem hiding this comment.
I can add a 😂 "huge" comment when we decided what is the right thing to do. As I mentioned && options.SerializerOptions.TypeInfoResolver is not DefaultJsonTypeInfoResolver can be easily removed, however, it will be useless, unless we change how the AddContext works (to prepend instead of append).
There was a problem hiding this comment.
unless we change how the
AddContextworks (toprependinstead ofappend)
After a conversation with @eiriktsarpalis, changing it doesn't make sense. As an example:
options.AddContext<Foo>();
options.AddContext<Bar>();
options.AddContext<Baz>();Should be equivalent to writing:
options.TypeInfoResolver = JsonTypeInfoResolver.Combine(Foo.Default, Bar.Default, Baz.Default);There was a problem hiding this comment.
The problem seems like the JSON fallback needs to be applied BEFORE the first class to AddContext to make everything work in all cases. Is that right? We don't want to override the reflection resolver if it'll eventually be newed up lazily by the the JSON library.
There was a problem hiding this comment.
JSON fallback needs to be applied BEFORE the first class to AddContext to make
After. but everything else is correct. I believe we should keep the options.SerializerOptions.TypeInfoResolver is not null to avoid breaking an app due to our internal context but I am less concerned about options.SerializerOptions.TypeInfoResolver is not DefaultJsonTypeInfoResolver since it will not make any difference, what do you think?
There was a problem hiding this comment.
I tend to agree with David that the source generated context could go first even in cases where you have reflection enabled. It would save you a relatively small amount of initialization costs, particularly around JITing all the dynamic methods that ProblemDetails requires. But maybe not a huge win if everything else is dynamically generated.
You wouldn't need to change the semantics of AddContext to achieve that though, you could simply use the Combine method to prepend whatever resolver you like to user configuration.
|
Closing this PR in favor of #46303. |
|
Hi @brunolins16. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
Fixes #46143
Waiting for #46303