aspnetcore: Cannot use JSON source generator with (HttpValidation)ProblemDetails
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
If the JSON source generator is enabled for the default JSON serializer options and an application uses the Results.Problem()
or Results.ValidationProblem()
methods, it is not possible to make the two work together.
If the HttpValidationProblemDetails
or ProblemDetails
is not registered with the JsonSerializerContext
, then an exception is thrown at runtime:
NotSupportedException: Metadata for type 'Microsoft.AspNetCore.Mvc.ProblemDetails' was not provided by TypeInfoResolver of type 'ApplicationJsonSerializerContext'. If using source generation, ensure that all root types passed to the serializer have been indicated with 'JsonSerializableAttribute', along with any types that might be serialized polymorphically.
If a developer attempts to add either type using [JsonSerializable]
, then the application fails to compile:
Project\Repro\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\ApplicationJsonSerializerContext.ProblemDetails.g.cs(24,120): error CS0122: 'ProblemDetailsJsonConverter' is inaccessible due to its protection level
Expected Behavior
An application is successfully able to use Results.Problem()
or Results.ValidationProblem()
with JSON source generators and Minimal APIs.
Steps To Reproduce
A full repro project is available at martincostello/problemdetails-json-source-generator-repro.
To reproduce, clone the project and run dotnet build
.
Exceptions (if any)
No response
.NET Version
7.0.100-preview.7.22377.5
Anything else?
I think something somewhere in the JSON source generator has become more strict beginning in .NET 7 preview 7, which is what brought this to my attention.
Previously I think the source generator would just fallback to using runtime serialization so things would “just work” without you needing to add the [JsonSerializable]
attribute.
It seems like it would be fairly trivial to fix this use case by making HttpValidationProblemDetailsJsonConverter
and ProblemDetailsJsonConverter
public instead of internal, but as they’re shared source that might cause other complications with multiple public types with the same name and namespace in different assemblies.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 23 (17 by maintainers)
@martincostello https://github.com/dotnet/aspnetcore/issues/44132 is completed and you should be able from .NET 8 Preview 2 source-gen a problemdetails, if needed
FWIW I should say that adding reflection-based fallback defeats the purpose of using source generators. It seems unfortunate that we need to rely on reflection (accidentally in .NET 6, explicitly starting with .NET 7) to add serialization support for the validation models. It sounds to me like MVC might want to expose a
JsonSerializerContext
for common model types so that users can add them to the mix without relying on reflection:cc @davidfowl
This seems related to an intentional breaking change we made in Preview 7. See https://github.com/dotnet/runtime/issues/71714 for more details and a workaround.
The error message appears related to a bug fixed recently in https://github.com/dotnet/runtime/issues/71714, cc @krwq.
@martincostello In .NET 8, we changed to when
AddProblemDetails
is called we combine our internalProblemDetailsJsonContext
, so, in most cases that will be enough. However, I am still trying to have this https://github.com/dotnet/aspnetcore/issues/44132 that will allow addProblemDetails
to yourJsonContext
The problem (at least in my case) is that I’m using source-gen with my MVC API. By default
HttpValidation/Validation/ProblemDetails
all cause serialization to fail since they’ve not been defined on theJsonSerializerContext
I’ve bound to Mvc’sJsonOptions
.The work-around is to enable the reflection-fallback but that seems like it defeats the purpose. If aspnet exposed a
JsonSerializerContext
for the*ProblemDetails
types we can combine that with our own context without needing to enable the reflection-fallback mode.@martincostello I worked with the JSON source generation for problem details when developing the
ProblemDetailsService
and just to let you know that probably you will face another problem when it is fixed because, by default, it will not fallback to reflection-based theExtensions
property fail to serialize.https://github.com/dotnet/aspnetcore/blob/7cb457bdaac8de9214391a9b9b273821d01c2300/src/Http/Http.Extensions/src/DefaultProblemDetailsWriter.cs#L54
Unless if you knowo all types that will be there at runtime and added then to your context.
https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-source-generation?pivots=dotnet-6-0#source-generation-support-in-aspnet-core