我一直在玩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。这是一个很好的方法吗?还是有一种更简单的方法使路由方案万无一失?
答案 0 :(得分:7)
如果这是您使用的默认路线:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
然后默认情况下将使用“HomeController”和“Index”操作,除非您的URL另有指定。
例如:
“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”将失败。
您可能已经知道我上面发布的所有内容。如果是这种情况,您是否会发布失败的网址,以便我们提供更好的帮助?
答案 1 :(得分:2)
我更喜欢为每个动作方法明确设置路线。
查看this。
答案 2 :(得分:1)
这是一个非常好的实用程序,可以帮助您调试路由:
答案 3 :(得分:0)
这个问题有点老了,但我遇到了同样的问题。
我不太热衷于手动定义大量路线,也不热衷于添加一系列属性来为我自动创建路线(Arnis'链接)。
经过一番考虑后,我决定使用我创建的简单RouteConstraint。我修改了默认路由以使用它并在默认值下面添加了我的404 catchall,如下所示:
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); } }
所使用的Reflection和LINQ的成本可能超过注册数百条路线的成本,但这对我来说似乎更清晰。