WEB API 未捕获 httpException
WEB API httpException is not caught
我有一个 WEB API 应用程序,我们在其中添加一些会话验证逻辑,然后调用基础 SendAsync 方法。
当我们传递包含大于 4MB 行的 byte[] 的请求时 response = await base.SendAsync(request, cancellationToken);
抛出一个 httpException "maximum request length exceeded",这没问题,可以通过 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;
}
}
What bothers me is that next step - it's still calling controller
method, where I can see that this byte[] parameter set to null.
当您调用 base.SendAsync(request, cancellationToken);
时,您实际上是在继续 WebAPI 管道,这最终会导致控制器被调用:
您真正想要的是在将请求发送到控制器之前检查 Content-Length
header。为此,您可以为请求的 header 检索它。如果大小超过,您可以 return 一个响应表明,否则,继续管道:
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
。
我有一个 WEB API 应用程序,我们在其中添加一些会话验证逻辑,然后调用基础 SendAsync 方法。
当我们传递包含大于 4MB 行的 byte[] 的请求时 response = await base.SendAsync(request, cancellationToken);
抛出一个 httpException "maximum request length exceeded",这没问题,可以通过 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;
}
}
What bothers me is that next step - it's still calling controller method, where I can see that this byte[] parameter set to null.
当您调用 base.SendAsync(request, cancellationToken);
时,您实际上是在继续 WebAPI 管道,这最终会导致控制器被调用:
您真正想要的是在将请求发送到控制器之前检查 Content-Length
header。为此,您可以为请求的 header 检索它。如果大小超过,您可以 return 一个响应表明,否则,继续管道:
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
。