-
Notifications
You must be signed in to change notification settings - Fork 10.1k
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
[AOT] Fixing the problems with ProblemDetails #45646
Conversation
// Use source generation serialization in two scenarios: | ||
// 1. There are no extensions. Source generation is faster and works well with trimming. | ||
// 2. Native AOT. In this case only the data types specified on ProblemDetailsJsonContext will work. | ||
if (context.ProblemDetails.Extensions is { Count: 0 } || !RuntimeFeature.IsDynamicCodeSupported) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eerhardt @jkotas @vitek-karas @davidfowl Like #45604 (comment), this is a place where dotnet/runtime#39806 would be useful.
Developers being able to run the "AOT path" while writing and debugging their app would help them find incompatible extension values during development instead of when they publish as AOT for production.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it fail to serialize if we did that in "build"? Or would the reflection based serializer kick in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would fail at runtime. This is what we're going to be doing manually today for AOT based JSON in ASP.NET Core. The reflection fallback would be disabled and our calls to resolve the JsonTypeInfo would return null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case - let's do dotnet/runtime#39806.
We just need to "hide" it enough so that people don't use it as the first option to solve AOT problems (still better than current behavior, but ideally we want them to really fix things)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me. I just had 2 nit comments.
It may be a good idea to get some AOT tests set up in the repo in a future PR. That way we can validate our workarounds for suppressions work correctly.
// Use source generation serialization in two scenarios: | ||
// 1. There are no extensions. Source generation is faster and works well with trimming. | ||
// 2. Native AOT. In this case only the data types specified on ProblemDetailsJsonContext will work. | ||
if (context.ProblemDetails.Extensions is { Count: 0 } || !RuntimeFeature.IsDynamicCodeSupported) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would probably be a good candidate for an "AOT-specific" test, similar to how we test trimming and AOT in dotnet/runtime. For example: https://github.com/dotnet/runtime/tree/main/src/libraries/System.Diagnostics.DiagnosticSource/tests/NativeAotTests.
ProblemDetails.Extensions
is problematic.Dictionary<string, object>
can contain any value, and the type needs to be serializable.Simply annotating all places that use
ProblemDetails.Extensions
as unsafe isn't a good solution. The developer exception middleware serializes problem details with extensions, and the middleware is extremely commonly used and is registered by default inWebApplication
:aspnetcore/src/DefaultBuilder/src/WebApplicationBuilder.cs
Line 148 in d2f7bd0
This PR tries to find a pragmatic middle ground that warns people about using extensions, but also makes some values safe so a user such as developer exception middleware can use it safely.
A short summary of what this PR tries to do:
Note: this PR builds on #45604. I split it out to make it clearer what changes are focused on
ProblemDetails
.Changes in PR:
ProblemDetails.Extensions
property now has warnings.[JsonConverter]
attributes on the types, so are never referenced in user code anyway.Dictionary<string, string[]> Errors { get; }
inHttpValidationProblemDetailsJsonConverter
manually. It's not difficult and avoids the problem of calling generated serialization inside a converter.DeveloperExceptionPageMiddlewareImpl
adds an anonymous type to extensions. This will never serialize, so it's been changed to a real type with a corresponding source generated serializer. It's converted into aJsonElement
which is added to extensions. The problem details writer supportsJsonElement
extension values.