c# – 创建两个不会在ASP.NET MVC中生成404错误的路由的问题

我正在尝试使用路由构建我的教程项目.我的主要目标是构建两条路线,在任何情况下都不会产生404错误.我的意思是,如果路径错误,我希望路由使用/ Home / Index路径.我有以下两条路线 –

    routes.MapRoute("Default", "{controller}/{action}", 
                        new {controller = "Home", action = "Index"}
                        );

    routes.MapRoute("Second", "{*catchall}",
                        new {controller = "Home", action = "Index", id = UrlParameter.Optional}
                        );

当我使用与第一条路线不匹配的不存在的路径时,它工作正常,像这样 –

c# – 创建两个不会在ASP.NET MVC中生成404错误的路由的问题

但如果确实如此,那么我有以下几点 –

c# – 创建两个不会在ASP.NET MVC中生成404错误的路由的问题

要么

c# – 创建两个不会在ASP.NET MVC中生成404错误的路由的问题

我理解它发生的原因.然而,目前,我只能找到“某种”解决方案.将以下代码添加到web.config文件 –

<customErrors mode="On">
      <error statusCode="404" redirect="~/Home/Index"/>
</customErrors>

但是,我不认为这是解决这个问题的最佳方法.因为,据我所知,它只是捕获所有错误并将其重定向到正确的路径,而不实际使用路由.所以我认为我不需要这种全局处理.

那么有人可以给我一个提示,或者为我提供一个很好的解决方案.谢谢.

解决方法:

好吧,你没有真正定义什么是“错误的”路由,所以这是我的定义:

>项目中不存在控制器或操作.
>如果传递了“id”,则它必须存在于action方法中.

路线

我使用约束来做到这一点. AFAIK,无法对可选参数使用约束.这意味着为了使id参数可选,您需要3条路线.

routes.MapRoute(
   name: "DefaultWithID",
   url: "{controller}/{action}/{id}",
   defaults: new { controller = "Home", action = "Index" },
   constraints: new { action = new ActionExistsConstraint(), id = new ParameterExistsConstraint() }
);

routes.MapRoute(
   name: "Default",
   url: "{controller}/{action}",
   defaults: new { controller = "Home", action = "Index" },
   constraints: new { action = new ActionExistsConstraint() }
);

routes.MapRoute(
    name: "Second",
    url: "{*catchall}",
    defaults: new { controller = "Home", action = "Index" }
);

ActionExistsConstraint

public class ActionExistsConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (routeDirection == RouteDirection.IncomingRequest)
        {
            var action = values["action"] as string;
            var controller = values["controller"] as string;

            var thisAssembly = this.GetType().Assembly;

            Type[] types = thisAssembly.GetTypes();

            Type type = types.Where(t => t.Name == (controller + "Controller")).SingleOrDefault();

            // Ensure the action method exists
            return type != null && type.GetMethod(action) != null;
        }

        return true;
    }
}

ParameterExistsConstraint

public class ParameterExistsConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (routeDirection == RouteDirection.IncomingRequest)
        {
            var action = values["action"] as string;
            var controller = values["controller"] as string;

            var thisAssembly = this.GetType().Assembly;

            Type[] types = thisAssembly.GetTypes();

            Type type = types.Where(t => t.Name == (controller + "Controller")).SingleOrDefault();
            var method = type.GetMethod(action);

            if (type != null && method != null)
            {
                // Ensure the parameter exists on the action method
                var param = method.GetParameters().Where(p => p.Name == parameterName).FirstOrDefault();
                return param != null;
            }
            return false;
        }

        return true;
    }
}
上一篇:javascript – 在运行时添加路由(ExpressJs)


下一篇:php – 如何在Laravel中为两种语言的路由生成URL