Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 如何处理MVC3路由的空参数字典错误?_Asp.net Mvc_Routes - Fatal编程技术网

Asp.net mvc 如何处理MVC3路由的空参数字典错误?

Asp.net mvc 如何处理MVC3路由的空参数字典错误?,asp.net-mvc,routes,Asp.net Mvc,Routes,我使用的大多数路由都基于标准MVC3应用程序中定义的默认路由: routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional })

我使用的大多数路由都基于标准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”被关闭,则会抛出null参数错误。显然,我的路由需要1,并且不是可选的,但我不想为我的每一个操作定义自定义路由。如果我打开自定义错误,我不确定这是什么类型的错误重定向到正确的html错误页面

问题: 我如何像处理404一样处理这个错误?我认为这种方法没有任何问题,因为事实上,在路由中省略Id号与404找不到相同

还是我在设计路线时遗漏了什么?对我来说似乎很直截了当

谢谢

更新: 我感谢下面给出的答案。它们都是合理的方法。为了更清楚地回答我的问题,让我再详细阐述一下。我认为“/Book/Update/1”的路线应该只有一个目的。更新第一册。任何其他与此的偏差都应该失败并重定向到404。我不认为这与不存在的静态html页面有什么不同。我可能会争论一个不包含在.net中的特性,我只是觉得有更简单的方法

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

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

public ActionResult Update(int? id)
{
    if (!id.HasValue) return HttpNotFound();

    //Debug.Assert(id.Value != null);
    ...
}
操作过滤器:

  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;
                }
            }
        }
    }
}

我用错误日志工具elmah对它进行了测试,它没有报告任何错误。

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

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,则检查它是否为可为null的类型,如果不是,则将重定向到您指定的位置。

我接受这一答案,但最后使用了OnActionExecuting筛选器属性。从那里我可以检查null id参数并重定向到我的自定义错误页面。我上面提供的链接提供了关于如何处理未知控制器和/或操作路由错误的信息。我极力推荐。
    [RequiredActionParameters("DetailsPageExceptionRedirect")]
    public ActionResult Details(int param1, int param2, bool param3, int? param4)