Request.ReadFromJsonAsync does not support quoted charset parameter values
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Describe the bug
When a client request contains a quoted charset in the content-type header (like `application/json; charset="utf-8"`), normal model binding works, but reading the JSON body manually with `ReadFromJsonAsync` generates an internal server error from an exception.
### Expected Behavior
`ReadFromJsonAsync` should be symmetrical with model binding and accept a quoted `charset` parameter.
### Steps To Reproduce
Using the following controller
```cs
[ApiController]
public class TestController : ControllerBase
{
[HttpPost("one")]
[Consumes("application/json")]
public int One([FromBody] Model model)
{
return model is not null ? 1 : 0;
}
[HttpPost("two")]
[Consumes("application/json")]
public async Task Two()
{
var model = await Request.ReadFromJsonAsync();
return model is not null ? 2 : 0;
}
}
public class Model
{
public required string Name { get; init; }
}
```
issue this request to both endpoints:
`curl -v -X POST -d '{"name":"a"}' -H 'Content-Type: application/json; charset="utf-8"' https://localhost:…/[one|two]`.
For `one`, there'll be a normal response, for `two`, there is an internal server error. With an unquoted `charset=utf-8`, both requests succeed.
### Exceptions (if any)
```
System.InvalidOperationException: Unable to read the request as JSON because the request content type charset '"utf-8"' is not a known encoding.
---> System.ArgumentException: '"utf-8"' is not a supported encoding name. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method. (Parameter 'name')
at System.Text.EncodingTable.InternalGetCodePageFromName(String name)
at System.Text.EncodingTable.GetCodePageFromName(String name)
at System.Text.Encoding.GetEncoding(String name)
at Microsoft.AspNetCore.Http.HttpRequestJsonExtensions.GetEncodingFromCharset(StringSegment charset)
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Http.HttpRequestJsonExtensions.GetEncodingFromCharset(StringSegment charset)
at Microsoft.AspNetCore.Http.HttpRequestJsonExtensions.ReadFromJsonAsync[TValue](HttpRequest request, JsonTypeInfo`1 jsonTypeInfo, CancellationToken cancellationToken)
at QuotedCharset.TestController.Two() in …TestController.cs:line 17
at lambda_method6(Closure, Object)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
```
### .NET Version
9.0.201
### Anything else?
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.