ASP.Net MVC路由策略

时间:2009-06-20 13:19:13

标签: asp.net-mvc routing

我一直在玩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。这是一个很好的方法吗?还是有一种更简单的方法使路由方案万无一失?

4 个答案:

答案 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)

这是一个非常好的实用程序,可以帮助您调试路由:

Phil Haack's Route Debugger

答案 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的成本可能超过注册数百条路线的成本,但这对我来说似乎更清晰。