我有一个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;
}
}
答案 0 :(得分:1)
困扰我的是下一步 - 它还在调用控制器 方法,我可以看到这个byte []参数设置为null。
当您致电base.SendAsync(request, cancellationToken);
时,您将有效地继续使用WebAPI管道,这最终会导致控制器被调用:
您真正想要的是在将请求发送到控制器之前检查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
。