2009-06-20 112 views
4

我一直在玩ASP.Net MVC一段时间了。我发现最困难的事情是路由表。ASP.Net MVC路由策略

我发现大多数例子都保留了默认路由。我发现这导致了很多错误,其中默认路由重定向到HomeController并且不存在的操作。导致奇怪的错误信息,你会看到一个简单的404。

我最终解决了路由设置,我明确定义了所有控制器/操作组合,我希望允许在最终重新定位到所有控制器/操作组合一个显示明智的错误信息的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。这是一个很好的方法来做到这一点,或者有一种更简单的方法来使路由方案更加简单吗?

+0

我在同一条船上来的。我认为如果默认路线无法找到控制器+操作,则所有捕获都会起作用。相反,控制器工厂会抛出异常。你还在走的是明确的路线吗? – dotjoe 2010-04-01 16:26:08

回答

7

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

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

则“的HomeController”和“索引”的行动将被默认使用,除非您的网址另有规定。

例如:

http://www.something.com/”将使用主控制器的索引操作,因为这些都是默认的控制器和行动。

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

http://www.something.com/foo/bar”将使用美孚控制器的“酒吧”行动

http://www.something.com/foo/bar/1”将使用美孚控制器的“酒吧”行动,通过“1”作为“ID”参数

如果你不没有“FooController”,任何以“http://www.something.com/foo”开头的内容都将失败。同样,如果您的FooController没有“Bar”动作,那么“http://www.something.com/foo/bar”将会失败。

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

+0

你实际上没有回答我的问题(我想这是我提出模糊问题的错误),但是你确实澄清了其他一些我不知道的事情,谢谢:-)我尝试清除这个问题。 – Mendelt 2009-06-20 15:28:11

2

我更喜欢为每个操作方法明确设置路径。

结账this

+0

感谢您的指针,将检查了这一点! – Mendelt 2009-06-20 15:12:54

0

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

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

经过一番考虑后,我决定使用我创建的简单RouteConstraint。我修改了默认路由使用它,并添加默认下面我404包罗万象的,就像这样:

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

routes.MapRoute(
    "CatchAll", 
    "{*catchall}", 
    new { controller = "Home", action = "NotFound" } 
); 

和约束类:

 
public class ExistingControllerActionConstraint : IRouteConstraint 
{ 
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     Type t = Type.GetType("MvcApplication_BareMinimum7.Controllers." + values["controller"] + "Controller"); 

     if (t == null) 
     { 
      return false; 
     } 

     MethodInfo mi = (from m in t.GetMethods() where m.Name == values["action"].ToString() select m).FirstOrDefault(); 

     return (mi != null); 
    } 
} 

反思的成本和LINQ使用可能超过注册数百条路线的成本,但这对我来说似乎更清洁。