【问题标题】:How do I handle null parameters dictionary error for MVC3 routes?如何处理 MVC3 路由的空参数字典错误?
【发布时间】:2012-03-14 21:34:29
【问题描述】:

我使用的大部分路由都是基于标准 MVC3 应用程序中定义的默认路由:

 routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional });

但是,如果我的路由是“/Book/Update/1”,并且因为用户手动键入了地址而没有 1,则忽略了“1”,则会引发空参数错误。显然我的路线需要这个 1 并且不是可选的,但我不会为我的每一个操作定义自定义路线。如果我打开自定义错误,我不确定这是重定向到正确的 html 错误页面的错误类型。

问题: 我该如何处理这个错误,就像它是 404 一样?我认为这种方法没有任何问题,因为现实情况是,在路由中省略 Id 编号与未找到 404 相同。

或者我在设计路线时遗漏了什么?对我来说似乎很简单。

谢谢。

更新: 我很欣赏下面给出的答案。它们都是合理的方法。为了更清楚地说明我的问题,让我再详细说明一下。在我看来,“/Book/Update/1”的路线应该只有一个目的。更新书 1。任何其他偏差都应该失败并重定向到 404。我认为这与不存在的静态 html 页面没有任何不同。我可能会争论 .net 中不包含的功能,我只是认为可能有更简单的方法。

更新 2: 应该挖得更深一点。有一个很好的例子here. 我发现第二个答案最有帮助。

【问题讨论】:

    标签: asp.net-mvc routes


    【解决方案1】:
    public ActionResult Update(int? id)
    {
        if (!id.HasValue) return HttpNotFound();
    
        //Debug.Assert(id.Value != null);
        ...
    }
    

    【讨论】:

    • 我接受了这个作为答案,但最后我使用了 OnActionExecuting 过滤器属性。从那里我可以检查空 id 参数并重定向到我的自定义错误页面。我上面提供的链接包含有关如何处理未知控制器和/或动作路由错误的信息。我强烈推荐。
    【解决方案2】:

    我也遇到了这个问题,我所做的是创建一个可重用的操作过滤器,在其中指定所需的参数。

    动作过滤器:

      public class RequiredActionParameters : ActionFilterAttribute
    {
        private readonly IEnumerable<string> _parameters;
    
        public RequiredActionParameters(params string[] parameters)
        {
            _parameters = parameters;
        }
    
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (!filterContext.IsChildAction && !filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
            {
                foreach (var parameter in _parameters)
                {
                    if (filterContext.ActionParameters[parameter] == null)
                    {
                        filterContext.Result = new RedirectResult("/Error/NotFound");
                        break;
                    }
                }
            }
        }
    }
    

    关于控制器中的动作:

     [RequiredActionParameters("restaurantId", "testId")]
     public ActionResult Details(long restaurantId, long testId)
     {
            View();
     }
    

    我用错误日志工具elmah测试了一下,没有报任何错误。

    【讨论】:

      【解决方案3】:

      我认识的派对迟到了,但希望这可能对其他人有所帮助。我在上面采纳了 Jamie 的答案并对其进行了扩展以使其更易于使用,因此您无需单独列出所有参数,允许来自不同操作的不同重定向并自动考虑可为空的类型参数。

      public class RequiredActionParametersAttribute : ActionFilterAttribute
      {
          private readonly string _redirectUrlConfigKey;
      
          public RequiredActionParametersAttribute(string redirectUrlConfigKey)
          {
              _redirectUrlConfigKey = redirectUrlConfigKey;
          }
      
          public override void OnActionExecuting(ActionExecutingContext filterContext)
          {
              if (string.IsNullOrWhiteSpace(_redirectUrlConfigKey))
                  return;
      
              var redirectUrl = ConfigurationManager.AppSettings[_redirectUrlConfigKey];
              if (string.IsNullOrWhiteSpace(redirectUrl))
                  return;
      
              var actionDescriptor = filterContext.ActionDescriptor;
              var parameterDescriptors = actionDescriptor.GetParameters();
      
              foreach (var parameter in filterContext.ActionParameters)
              {
                  if (parameter.Value == null)
                  {
                      var parameterDescriptor = parameterDescriptors.First(p => p.ParameterName == parameter.Key);
                      if (!IsNullableType(parameterDescriptor.ParameterType))
                      {
                          filterContext.Result = new RedirectResult(redirectUrl);
                          break;
                      }
                  }
              }
          }
      
          private static bool IsNullableType(Type type)
          {
              return Nullable.GetUnderlyingType(type) != null;
          }
      }
      

      接着行动

          [RequiredActionParameters("DetailsPageExceptionRedirect")]
          public ActionResult Details(int param1, int param2, bool param3, int? param4)
      

      您可以为配置文件中的不同操作添加不同的重定向,并将配置键传递给操作过滤器。然后它会检查每个参数是否存在,如果为 null,则检查它是否为可空类型,否则将重定向到您指定的位置。

      【讨论】:

        猜你喜欢
        • 2023-03-05
        • 2020-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-28
        • 1970-01-01
        • 1970-01-01
        • 2020-10-04
        相关资源
        最近更新 更多