忽略由于缺少控制器参数而导致的异常 [英] Ignore exceptions caused by missing controller parameters
问题描述
我有一个使用MVC4构建的面向互联网的网站,偶尔会收到发送不完整URL请求的漫游器或好奇的用户的错误报告.
I have an internet-facing website that's built using MVC4 and I occasionally get error reports from bots or curious users who send requests for incomplete URLs.
例如:
public class ProductController : Controller
{
[HttpGet]
public void View(int id)
{
// ...
- 对
/product/view/1
的GET请求有效. - 由于未指定参数,因此对
/product/view
的GET请求无效. - A GET request to
/product/view/1
is valid. - A GET request to
/product/view
is invalid as the argument is not specified.
此类无效请求会引发类似以下的异常:
Such invalid requests raise exceptions resembling:
System.ArgumentException: The parameters dictionary contains a null entry
for parameter 'id' of non-nullable type 'System.Int32' for method
'System.Web.Mvc.ActionResult View(Int32)' in 'Foo.ProductController'. An
optional parameter must be a reference type, a nullable type, or be declared
as an optional parameter.
Parameter name: parameters
at System.Web.Mvc.ActionDescriptor.ExtractParameterFromDictionary(ParameterInfo parameterInfo, IDictionary`2 parameters, MethodInfo methodInfo)
at System.Web.Mvc.ReflectedActionDescriptor.<>c__DisplayClass1.<Execute>b__0(ParameterInfo parameterInfo)
...
作为异常消息的状态,我可以使 id
参数为可空状态并在action方法中进行检查,但是我有 many 个控制器,其中 many >操作.
As the exception message states, I could make the id
argument nullable and check within the action method, but I have many controllers with many actions.
对于任何未能将参数绑定到动作参数的请求,我想返回 BadRequest
/ NotFound
响应,并在代码的单个位置指定适用于所有控制器.
I'd like to return a BadRequest
/NotFound
response to any request that fails to bind arguments to action parameters, and specify this in a single place in code to apply across all controllers.
这怎么办?
推荐答案
一种可行的方法是在控制器中重写 OnActionExecuted
(我使用基本控制器,因此将其放在此处.)
One approach that seems to work is to override OnActionExecuted
in the controller (I use a base controller, so would put it there.)
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Exception == null)
return;
// Avoid 'action parameter missing' exceptions by simply returning an error response
if (filterContext.Exception.TargetSite.DeclaringType == typeof(ActionDescriptor) &&
filterContext.Exception.TargetSite.Name == "ExtractParameterFromDictionary")
{
filterContext.ExceptionHandled = true;
filterContext.Result = new HttpStatusCodeResult((int)HttpStatusCode.BadRequest);
}
}
这样做可能会有些不舒服,因为它可能会在将来的框架版本中中断.但是,如果确实发生故障,则该站点将恢复为返回500,而不是返回400.
It feels a little uncomfortable to do this as it may break in future versions of the framework. However if it does break, then the site will revert to returning 500's instead of 400's.
这篇关于忽略由于缺少控制器参数而导致的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!