Improve error messages for implicit and explicit FromBody attribute in Minimal API #35086#35188
Conversation
|
I think we should split this into two PRs. One for throwing for multiple from-body parameters during Create() and another for throwing for not finding a body when one is expected during the request. |
| if (parameterName is not null && factoryContext.TrackedParameters.ContainsKey(parameterName)) | ||
| { | ||
| factoryContext.TrackedParameters.Remove(parameterName); | ||
| factoryContext.TrackedParameters.Add(parameter.Name!, "We failed to infer this parameter. Did you forget to inject it as a Service in the DI container?"); |
There was a problem hiding this comment.
| factoryContext.TrackedParameters.Add(parameter.Name!, "We failed to infer this parameter. Did you forget to inject it as a Service in the DI container?"); | |
| factoryContext.TrackedParameters.Add(parameter.Name!, "UNKNOWN"); |
I think the following is a bit hard to read:
Unhandled exception. System.InvalidOperationException: Failure to infer one or more parameters. Below is the list of parameters we found:
Parameter Source
sampleDTO Body Attribute
userRepo We failed to infer this parameter. Did you forget to inject it as a Service?
at Microsoft.AspNetCore.Http.RequestDelegateFactory.CreateArguments(ParameterInfo[] parameters, FactoryContext factoryContext) in C:\Users\rassumani\bench\aspnetcore\src\Http\Http.Extensions\src\RequestDelegateFactory.cs:line 209
at Microsoft.AspNetCore.Http.RequestDelegateFactory.CreateTargetableRequestDelegate(MethodInfo methodInfo, RequestDelegateFactoryOptions options, Expression targetExpression) in C:\Users\rassumani\bench\aspnetcore\src\Http\Http.Extensions\src\RequestDelegateFactory.cs:line 170
...
This would be a bit better:
Unhandled exception. System.InvalidOperationException: Failure to infer one or more parameters. Below is the list of parameters we found:
Parameter | Source
----------+------------------
sampleDTO | Body (Attribute)
userRepo | UNKOWN
Did you forget to inject the "UNKNOWN" parameters as a Service?
at Microsoft.AspNetCore.Http.RequestDelegateFactory.CreateArguments(ParameterInfo[] parameters, FactoryContext factoryContext) in C:\Users\rassumani\bench\aspnetcore\src\Http\Http.Extensions\src\RequestDelegateFactory.cs:line 209
at Microsoft.AspNetCore.Http.RequestDelegateFactory.CreateTargetableRequestDelegate(MethodInfo methodInfo, RequestDelegateFactoryOptions options, Expression targetExpression) in C:\Users\rassumani\bench\aspnetcore\src\Http\Http.Extensions\src\RequestDelegateFactory.cs:line 170
...
Adding the | and - would require more than just the suggested fix of course but I think it will help. Can you show what this looks like on the developer exception page?
There was a problem hiding this comment.
Also, do we get the same "Failure to infer one or more parameters." error when all the parameters have explicit attributes? If there actually are multiple [FromBody] attributes we should probably just continue saying that's not allowed instead of saying we couldn't infer the source.
There was a problem hiding this comment.
Do we have a logger formatter or console formatter in aspnetcore that I can use ?
There was a problem hiding this comment.
I am hoping an analyzer will prevent the double explicit [FromBody] right away.
There was a problem hiding this comment.
New formatting. Not perfect, visually readable.
Unhandled exception. System.InvalidOperationException: Failure to infer one or more parameters.
Below is the list of parameters that we found:
Parameter |Source
---------------------------------------------------------------------------------
id | Route (Inferred)
dto | Body (Attribute)
dto1 | UNKNOWN
repo | Service (Attribute)
repo1 | UNKNOWN
Did you forget to inject the "UNKNOWN" parameters as a Service?
at Microsoft.AspNetCore.Http.RequestDelegateFactory.CreateArguments(ParameterInfo[] parameters, FactoryContext factoryContext) in C:\Users\rassumani\bench\aspnetcore\src\Http\Http.Extensions\src\RequestDelegateFactory.cs:line 196
at Microsoft.AspNetCore.Http.RequestDelegateFactory.CreateTargetableRequestDelegate(MethodInfo methodInfo, RequestDelegateFactoryOptions options, Expression targetExpression) in C:\Users\rassumani\bench\aspnetcore\src\Http\Http.Extensions\src\RequestDelegateFactory.cs:line 165
at Microsoft.AspNetCore.Http.RequestDelegateFactory.Create(Delegate action, RequestDelegateFactoryOptions options) in C:\Users\rassumani\bench\aspnetcore\src\Http\Http.Extensions\src\RequestDelegateFactory.cs:line 84
There was a problem hiding this comment.
"Did you mean to register the "UNKNOWN" parameters as a Service?"
There was a problem hiding this comment.
Unhandled exception. System.InvalidOperationException: Failure to infer one or more parameters.
Below is the list of parameters that we found:
Parameter |Source
---------------------------------------------------------------------------------
id | Route (Inferred)
dto | Body (Attribute)
dto1 | UNKNOWN
repo | Service (Attribute)
repo1 | UNKNOWN
Did you mean to register the "UNKNOWN" parameters as a Service?
at Microsoft.AspNetCore.Http.RequestDelegateFactory.CreateArguments(ParameterInfo[] parameters, FactoryContext factoryContext) in C:\Users\rassumani\bench\aspnetcore\src\Http\Http.Extensions\src\RequestDelegateFactory.cs:line 196
at Microsoft.AspNetCore.Http.RequestDelegateFactory.CreateTargetableRequestDelegate(MethodInfo methodInfo, RequestDelegateFactoryOptions options, Expression targetExpression) in C:\Users\rassumani\bench\aspnetcore\src\Http\Http.Extensions\src\RequestDelegateFactory.cs:line 165
at Microsoft.AspNetCore.Http.RequestDelegateFactory.Create(Delegate action, RequestDelegateFactoryOptions options) in C:\Users\rassumani\bench\aspnetcore\src\Http\Http.Extensions\src\RequestDelegateFactory.cs:line 84
|
|
||
| if (parameterCustomAttributes.OfType<IFromRouteMetadata>().FirstOrDefault() is { } routeAttribute) | ||
| { | ||
| factoryContext.TrackedParameters.Add(parameter.Name, RequestDelegateFactoryConstants.RouteAttribue); |
There was a problem hiding this comment.
Great call to add a separate class for all the constants we're introducing here.
| args[i] = CreateArgument(parameters[i], factoryContext); | ||
| } | ||
|
|
||
| if(factoryContext.HasMultipleBodyParameters) |
There was a problem hiding this comment.
Super nit:
| if(factoryContext.HasMultipleBodyParameters) | |
| if (factoryContext.HasMultipleBodyParameters) |
| // when RDF.Create is manually invoked. | ||
| if (factoryContext.RouteParameters is { } routeParams) | ||
| { | ||
| factoryContext.TrackedParameters.Add(parameter.Name, RequestDelegateFactoryConstants.RouteParameter); |
There was a problem hiding this comment.
This isn't correct anymore. It's either route or query or either.
Improve error messages for implicit and explicit FromBody attribute in Minimal API #35086
PR Description
This a draft PR to start the conversation on a possible solution for error messages when :
Example:
In the example above, the code changes will keep track of all the request parameters and provide an error message telling the user which parameters we could successfully infer which ones fail. It also adds the parameter source (From Query String, Route, Services, etc.)
We will read the body
httpContext.Request.ReadFromJsonAsync(bodyType)and throw an exception in CreateContentTypeError method.Exception:
Fixes #35086