忽略由于缺少控制器参数而导致的异常 [英] Ignore exceptions caused by missing controller parameters

查看:51
本文介绍了忽略由于缺少控制器参数而导致的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆