RequestSizeLimitAttribute:HTTP 500而不是ASP.NET Core 2.1.401中的413

时间:2018-09-09 11:11:21

标签: c# asp.net-core

我的API控制器上有[RequestSizeLimit],并且它 kinda 可以正常工作:大于指定限制的请求将被拒绝。

    [HttpPut]
    [RequestSizeLimit(120_000_000)]
    public async Task<IActionResult> Put(IFormCollection form)
    {
       ...
    }

问题是,抛出了异常:

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)

因此返回了HTTP 500,但是我希望是413或400。而且我也不希望出现异常,因为这是完全正常的情况。

找不到与此相关的任何文档。对于太大的请求返回413的正确方法是什么?

2 个答案:

答案 0 :(得分:4)

Kestrel响应为413 Payload Too Large,但HttpSys响应为通用500 Internal Server Error响应。我假设您使用第二个。在这种情况下,您可以实现异常处理中间件来处理这种情况:

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;
        }
    }
}

并在Startup.cs中的“ Configure”中注册它:

public void Configure(IApplicationBuilder app)
{
    ...
    app.UseMiddleware<ExceptionMiddleware>();
    ...
}

您也可以使用Exception filter

答案 1 :(得分:0)

我在 Visual Studio 中调试时遇到了同样的问题。我发现 DeveloperExceptionPageMiddleware 导致它。我在 fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware 异常上方的服务器日志中注意到 BadHttpRequestException

从我的 Startup.cs 中删除它会按预期提供 413 个响应。

if (env.IsDevelopment())
    app.UseDeveloperExceptionPage();

现在服务器日志改为显示 fail: Microsoft.AspNetCore.Server.Kestrel