C# 未捕获WEB API httpException

C# 未捕获WEB API httpException,c#,asp.net-web-api,asp.net-web-api2,C#,Asp.net Web Api,Asp.net Web Api2,我有一个WEB API应用程序,我们在其中添加了一些会话验证逻辑,然后调用基本SendAsync方法 当我们传递包含大于4MB的字节[]的请求时,lineresponse=wait base.SendAsync(请求,取消令牌)抛出httpException“超出最大请求长度”,这是正常的,可以通过IIS设置进行管理。困扰我的是下一步——它仍然在调用controller方法,我可以看到这个byte[]参数设置为null。控制器方法抛出ArgumentNullException,这是最终用户得到的

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

当我们传递包含大于4MB的字节[]的请求时,line
response=wait base.SendAsync(请求,取消令牌)抛出httpException“超出最大请求长度”,这是正常的,可以通过IIS设置进行管理。困扰我的是下一步——它仍然在调用controller方法,我可以看到这个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;
   }
}
公共类sessiondHandler:DelegatingHandler
{
受保护的覆盖异步任务SendAsync(
HttpRequestMessage请求,
取消令牌(取消令牌)
{
//这里有一些额外的逻辑
HttpResponseMessage响应;
尝试
{
response=wait base.sendaync(请求、取消令牌);
}
捕获(例外e)
{
响应=新的HttpResponseMessage(HttpStatusCode.Forbidden)
{
Content=newstringcontent(例如,Message,Encoding.UTF8,“应用程序/json”)
};
}
最后
{
如果(签名人)
{
签核(sessionId);
}
}
返回响应;
}
}
困扰我的是下一步——它仍然在呼叫控制器 方法,我可以看到这个byte[]参数设置为null

当您调用
base.SendAsync(请求、取消令牌)时,您实际上是在继续WebAPI管道,这将最终导致调用控制器:

实际上,您需要在将请求发送到控制器之前检查
内容长度
标题。您可以通过为请求的标头检索它来实现这一点。如果大小超过,则可以返回一个响应,指示继续管道:

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);
}
受保护的覆盖任务SendAsync(
HttpRequestMessage请求,
取消令牌(取消令牌)
{
//4MB,也许您希望像其他请求一样将其放宽一点
//特性会影响尺寸。
常量int maxRequestSize=4194304;
IEnumerable contentLengthHeader;
request.Headers.TryGetValues(“内容长度”,out contentLengthHeader);
var contentLength=contentLengthHeader.FirstOrDefault();
if(contentLength==null)
{
//未发送内容长度,请决定要执行的操作。
}
长实际内容长度;
如果(!long.TryParse(contentLength,out实际contentLength))
{
//无法分析,无法决定要执行的操作。
}
如果(实际内容长度>最大请求大小)
{
//如果达到,则请求的内容长度太大。
//返回错误响应:
返回Task.FromResult(request.CreateErrorResponse(HttpStatusCode.Forbidden),
Format(“请求大小超过了{0}字节”,maxRequestSize));
}
返回base.sendaync(请求、取消令牌);
}

如果您不希望对WebAPI应用程序中的所有控制器进行此检查,您可以。

您提到的控制器方法是什么?这是不是
Signoff(sessionId)?
除非我被误解,否则这不是默认的
try catch finally
行为吗?不,控制器方法不是直接从上面的代码调用的。它是AddDocument方法,请求中描述了它,上面的代码拦截了它一段时间,以便检查会话。@mattytommo,默认行为是什么意思?因为我没弄错,任务通常会抛出aggreateeexception。在这里,我从对base.SendAsync方法的调用中抛出了两个异常,我只得到了最后一个异常。我希望有一个不是聚合,就是先发生的。谢谢你,@Yuval Itzzakov,但我不想在后台的某个地方用.NET代码为我检查请求长度,从而复制逻辑。此外,如果我使用常量const int maxRequestSize=4194304;然后有人更改IIS设置,这将导致不正确的行为。@Olga这只是为了演示。如果愿意,您可以从IIS配置的设置中读取此内容。好的,但无论如何,它将复制逻辑。好吧,我想,如果没有其他事情出现,我最终会这么做的。非常感谢。