未捕获WEB API httpException

时间:2015-06-12 11:58:23

标签: c# asp.net-web-api asp.net-web-api2

我有一个WEB API应用程序,我们在其中添加一些会话验证逻辑,然后调用基本SendAsync方法。

当我们传递包含byte []的请求时,大于4MB的行response = await base.SendAsync(request, cancellationToken);会抛出一个httpException"超过最大请求长度",这是可以的,可以通过IIS设置进行管理。困扰我的是下一步 - 它还在调用控制器方法,我可以看到这个byte []参数设置为null。控制器方法抛出ArgumentNullException,这是最终用户获得的。

首先,我无法理解为什么在HttpException之后仍会调用控制器方法。更重要的是我如何设法捕获此HttpException,以便最终用户将看到实际原因,为什么请求未被处理。 提前谢谢。

public class SessionIdHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        //some additional logic here
        HttpResponseMessage response;
        try
        {
            response = await base.SendAsync(request, cancellationToken);
        }
        catch (Exception e)
        {
            response = new HttpResponseMessage(HttpStatusCode.Forbidden)
            {
                Content = new StringContent(e.Message, Encoding.UTF8, "application/json")
            };
        }
        finally
        {
            if (signedOnHere)
            {
                Signoff(sessionId);
            }
        }
        return response;
   }
}

1 个答案:

答案 0 :(得分:1)

  

困扰我的是下一步 - 它还在调用控制器   方法,我可以看到这个byte []参数设置为null。

当您致电base.SendAsync(request, cancellationToken);时,您将有效地继续使用WebAPI管道,这最终会导致控制器被调用:

WebAPI pipeline

您真正想要的是在将请求发送到控制器之前检查Content-Length标题。您可以通过检索请求的标头来执行此操作。如果大小超过,您可以返回一个响应,指示否则,继续管道:

protected override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request, 
            CancellationToken cancellationToken)
{
    // 4MB, perhaps you want to loosen this up a bit as other request
    // characteristics will effect the size.
    const int maxRequestSize = 4194304;

    IEnumerable<string> contentLengthHeader;
    request.Headers.TryGetValues("Content-Length", out contentLengthHeader);

    var contentLength = contentLengthHeader.FirstOrDefault();
    if (contentLength == null)
    {
        //No content-length sent, decide what to do.
    }

    long actualContentlength;
    if (!long.TryParse(contentLength, out actualContentlength))
    {
        // Couldn't parse, decide what to do.
    }

    if (actualContentlength > maxRequestSize)
    {
        // If reached, the content-length of the request was too big. 
        // Return an error response:
        return Task.FromResult(request.CreateErrorResponse(HttpStatusCode.Forbidden,
            string.Format("Request size exceeded {0} bytes", maxRequestSize)));
    }
    return base.SendAsync(request, cancellationToken);
}

如果您不希望对WebAPI应用程序中的所有控制器进行此检查,则可以pre-route each DelegatingHandler