【问题标题】:ASP.Net MVC routing strategyASP.Net MVC 路由策略
【发布时间】:2010-11-04 12:43:18
【问题描述】:

我玩 ASP.Net MVC 已经有一段时间了。我发现最难做的就是路由表。

我发现大多数示例都保留了默认路由。我发现这会导致很多错误,默认路由重定向到 HomeController 的操作不存在。导致奇怪的错误消息,您希望看到一个简单的 404。

我最终选择了一个路由设置,在该设置中,我明确定义了我希望允许的所有控制器/操作组合,并在最后使用一个 catch-all 重定向到显示合理错误消息的 404 页面。

我在这里遗漏了什么吗?或者这确实是一种很好的做事方式?


看看我得到的答案,我想我最好澄清一下这个问题。

我正在尝试对我正在构建的网站的路由方案进行验证。我注意到当我离开默认的 {controller}/{action}/{id} 路由时,我想显示 404 错误的各种 URL 实际上被路由到带有无效操作的 HomeController 并导致一些丑陋的错误而是发消息。

我有点困惑,因为大多数代码示例都保留在默认路由中。它的存在是有原因的还是可以删除它?

我现在使用的方案有点像这样

        routes.MapRoute( "About", "About", new {controller = "Page", action = "About"} );
        routes.MapRoute( "SignIn", "SignIn", new {controller = "Page", action = "SignIn"} );
        routes.MapRoute( "SignOut", "SignOut", new {controller = "Page", action = "SignOut"} );
        routes.MapRoute( "Authenticate", "Authenticate", new { controller = "Authentication", action = "Authenticate" });

        routes.MapRoute("CatchAll", "{*url}", new { controller = "Error", action = "Http404" });

我已经为系统中的每个操作指定了一条路线。并在最后显示 404。这是执行此操作的好方法还是有更简单的方法可以使路由方案万无一失?

【问题讨论】:

  • 我在同一条船上。我认为如果默认路由找不到控制器+动作,catch all 会起作用。相反,控制器工厂会引发异常。你还在走明确的路线吗?

标签: asp.net-mvc routing


【解决方案1】:

这是一个非常好的工具,可以帮助您调试路由:

Phil Haack's Route Debugger

【讨论】:

    【解决方案2】:

    这个问题有点老了,但我刚刚遇到它,有同样的问题。

    我不太热衷于手动定义大量路由,也不热衷于添加一堆属性来自动为我创建路由(Arnis 的链接)。

    经过一番考虑,我决定使用我创建的简单 RouteConstraint。我修改了默认路由以使用它,并将我的 404 总括添加到默认路由下方,如下所示:

    路线.MapRoute( “默认”, "{controller}/{action}/{id}", 新的{控制器=“家”,动作=“索引”,id=“”}, 新的 { 控制器 = 新的 ExistingControllerActionConstraint() } ); 路线.MapRoute( “一网打尽”, "{*catchall}", 新{控制器=“家”,动作=“未找到”} );

    以及约束类:

    公共类 ExistingControllerActionConstraint : IRouteConstraint { public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { 类型 t = Type.GetType("MvcApplication_BareMinimum7.Controllers." + values["controller"] + "Controller"); 如果(t == null) { 返回假; } MethodInfo mi = (from m in t.GetMethods() where m.Name == values["action"].ToString() select m).FirstOrDefault(); 返回(mi!= null); } }

    使用反射和 LINQ 的成本可能超过注册数以百计的路由的成本,但这对我来说似乎更干净。

    【讨论】:

      【解决方案3】:

      我更喜欢为每个操作方法显式设置路由。

      查看this

      【讨论】:

        【解决方案4】:

        如果这是您使用的默认路由:

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

        除非您的 URL 另有说明,否则默认情况下将使用“HomeController”和“Index”操作。

        例如:

        "http://www.something.com/" 将使用 Home 控制器的 Index 动作,因为它们是默认的控制器和动作。

        "http://www.something.com/foo" 将使用 Foo 控制器的 Index 操作,因为 "Index" 是默认操作。

        "http://www.something.com/foo/bar" 将使用 Foo 控制器的 "bar" 动作

        "http://www.something.com/foo/bar/1" 将使用 Foo 控制器的 "bar" 动作,将 "1" 作为 "id" 参数传递

        如果你没有“FooController”,任何以“http://www.something.com/foo”开头的东西都会失败。同样,如果您的 FooController 没有“Bar”操作,则“http://www.something.com/foo/bar”将失败。

        您可能已经知道我在上面发布的所有内容。如果是这种情况,您会发布失败的 URL,以便我们更好地提供帮助吗?

        【讨论】:

        • 您实际上并没有回答我的问题(我想这是我提出模糊问题的错),但您确实澄清了一些我不知道的其他事情,谢谢 :-) 我试图澄清问题位。
        猜你喜欢
        • 2012-10-06
        • 1970-01-01
        • 1970-01-01
        • 2011-01-04
        • 1970-01-01
        • 2015-10-25
        • 2012-02-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多