我有一个使用 MVC4 构建的面向 Internet 的网站,我偶尔会收到来自发送不完整 URL 请求的机器人或好奇用户的错误报告。
例如:
public class ProductController : Controller
{
[HttpGet]
public void View(int id)
{
// ...
- 对
/product/view/1
的 GET 请求有效。 - 对
/product/view
的 GET 请求无效,因为未指定参数。
此类无效请求会引发类似以下的异常:
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
参数可为 null 并在操作方法中进行检查,但我有许多 Controller 和许多 Action 。
我想对任何未能将参数绑定(bind)到操作参数的请求返回一个 BadRequest
/NotFound
响应,并在代码中的一个地方指定它适用于所有 Controller 。
如何做到这一点?
最佳答案
一种似乎有效的方法是覆盖 Controller 中的 OnActionExecuted
(我使用基本 Controller ,所以会把它放在那里。)
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);
}
}
这样做感觉有点不舒服,因为它可能会在框架的 future 版本中崩溃。但是,如果它确实中断,则该站点将恢复为返回 500 而不是 400。
关于c# - 忽略 Controller 参数缺失引起的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19379168/