I have [RequestSizeLimit]
on my API controller, and it kinda works as expected: requests bigger than specified limit are rejected.
[HttpPut]
[RequestSizeLimit(120_000_000)]
public async Task<IActionResult> Put(IFormCollection form)
{
...
}
The problem is, an exception is thrown:
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Request body too large.
at Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException.Throw(RequestRejectionReason reason)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1MessageBody.ForContentLength.OnReadStarting()
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.MessageBody.TryInit()
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.MessageBody.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.ReadAsyncInternal(Memory`1 buffer, CancellationToken cancellationToken)
So HTTP 500 is returned, but I would expect 413 or 400. And I don't expect an exception, since this is a perfectly normal situation.
Could not find any documentation on this. What is the right way to return 413 for requests that are too big?
By default, ASP.NET and IIS protect us from large requests by putting hard limits on the transmitted size. IIS buffers files in our server’s memory before passing the byte array to ASP.NET. IIS’ default limit is 4MB and ASP.NET Core has a default of 30MB. To put that in perspective, one 12 megapixels digital picture can average 3.6 megabytes.
Which server are you using? For Nginx users, the directive which determines what the allowable HTTP request size can be is client_max_body_size, the default maximum allowable request size is 1MB. The limit in Apache is set via the LimitRequestBody directive and defaults to 0 (meaning unlimited) to 2147483647 (2GB).
Unfortunately when sending the request I receive an error: Response status code does not indicate success: 413 (Request Entity Too Large). The error only seems to occur when the file is large to begin with, which makes sense.
In ASP.NET Core, returning status code is easier than you might think. HTTP response status codes have so much importance in REST API’s. In any case if you want to return a status code from your ASP.NET Core API, all you have to do is in your controller method,
Kestrel responds with a 413 Payload Too Large response, but HttpSys responds with a generic 500 Internal Server Error response. I assume you use the second one. In this case you can implement Exception handling middelware to handle this case:
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
public ExceptionMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext)
{
try
{
await _next(httpContext);
}
catch (Exception ex)
{
HandleExceptionAsync(httpContext, ex);
}
}
private static void HandleExceptionAsync(HttpContext context, Exception exception)
{
if (exception is BadHttpRequestException badRequestException && badRequestException.Message == "Request body too large.")
{
context.Response.StatusCode = (int) HttpStatusCode.RequestEntityTooLarge;
}
}
}
And register it in Configure in Startup.cs:
public void Configure(IApplicationBuilder app)
{
...
app.UseMiddleware<ExceptionMiddleware>();
...
}
As alternative you can also use Exception filter
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With