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

C# RequestSizeLimitAttribute:HTTP 500而不是ASP.NET Core 2.1.401中的413,c#,asp.net-core,C#,Asp.net Core,我的API控制器上有[RequestSizeLimit],它可以像预期的那样工作:大于指定限制的请求被拒绝 [HttpPut] [RequestSizeLimit(120_000_000)] public async Task<IActionResult> Put(IFormCollection form) { ... } 所以HTTP 500返回,但我希望是413或400。我不希望有例外,因为这是一个完全正常的情况 找不到有关

我的API控制器上有
[RequestSizeLimit]
,它可以像预期的那样工作:大于指定限制的请求被拒绝

    [HttpPut]
    [RequestSizeLimit(120_000_000)]
    public async Task<IActionResult> Put(IFormCollection form)
    {
       ...
    }
所以HTTP 500返回,但我希望是413或400。我不希望有例外,因为这是一个完全正常的情况


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

Kestrel以413负载太大的响应进行响应,但HttpSys以通用的500内部服务器错误响应进行响应。我想你用的是第二个。在这种情况下,您可以实现异常处理中间件来处理这种情况:

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>();
    ...
}
public void配置(IApplicationBuilder应用程序)
{
...
app.UseMiddleware();
...
}

作为替代方法,您也可以使用

在Visual Studio中运行调试时,我遇到了相同的行为。我发现是
DeveloperExceptionPageMiddleware
导致了它。我注意到
失败:Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware
服务器日志中的
BadHttpRequestException
异常

从my
Startup.cs
中删除此选项,将获得413个预期响应

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

现在,服务器日志显示
fail:Microsoft.AspNetCore.server.Kestrel

我使用Kestrel(如堆栈跟踪所示)。该应用程序使用MS docker image在Linux上运行。@PavelTupitsyn,嗯,那么它可以是特定于Linux的。无论如何,建议的解决方案应该会有所帮助。它不是特定于Linux的,同样的事情也会发生在windows上。不过,您的解决方案很有效,谢谢!提交了一个问题:文本检查在这个中间件中不起作用,因为它不是一个BadHttpRequestException,它是一个IOException,请参阅github上的代码,文本也是$“请求的内容长度{contentLength.Value}大于请求体大小限制{uMaxSize.Value}。”;
if (env.IsDevelopment())
    app.UseDeveloperExceptionPage();