2011-11-04 30 views
4

我期待符合这些模式设置路线:如何设置复杂的路由在asp.net MVC

/users 
Mapped to action GetAllUsers() 

/users/12345 
Mapped to action GetUser(int id) 

/users/1235/favorites 
mapped to action GetUserFavorites(int id) 

控制器应始终是UsersController。我认为这会起作用,但事实并非如此。

routes.MapRoute("1", 
       "{controller}/{action}/{id}", 
       new { id = UrlParameter.Optional, action = "index" }); 

routes.MapRoute("2", 
       "{controller}/{id}/{action}"); 

我正在努力把头围住它。任何帮助将非常感激。

+2

[使用路由调试器!](http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx) – bzlm

+0

+1 for @bzlm - 我没有意识到该工具 - 谢谢 – iandotkelly

回答

10

为了实现你的目标,你需要三个独立的路线在的global.asax.cs RegisterRoutes,应该按以下顺序进行添加,且必须是Default路线之前(假定ID必须为整数) :

routes.MapRoute(
    "GetUserFavorites", // Route name 
    "users/{id}/favorites", // URL with parameters 
    new { controller = "Users", action = "GetUserFavorites" }, // Parameter defaults 
    new { id = @"\d+" } // Route constraint 
); 

routes.MapRoute(
    "GetUser", // Route name 
    "users/{id}", // URL with parameters 
    new { controller = "Users", action = "GetUser" } // Parameter defaults 
    new { id = @"\d+" } // Route constraint 
); 

routes.MapRoute(
    "GetAllUsers", // Route name 
    "users", // URL with parameters 
    new { controller = "Users", action = "GetAllUsers" } // Parameter defaults 
); 
+0

所以没有通用的方式来设置它,以便我不必硬编码操作或控制器名称? – Micah

+0

鉴于您列出的要求,路由必须非常具体。但是,如果您的控制器具有一致的URL命名方案和一致的操作名称,则可以制定规则以服务于多个控制器,而不仅仅是您的用户控制器。 – counsellorben

+0

@Micah - 是的,但不是您在问题中指出的从URL到Action的映射。我增加了这个到我的答案,因为有更多的空间。 – iandotkelly

3

counsellorben在我做之前就得到了答案。如果你想要那些确切的URL和那些确切的方法,那么这是唯一的方法。您可以通过将GetUser和GetAllUsers组合成一个具有可为空的id的动作来减少路由的数量,例如,

routes.MapRoute(
    "GetUser", 
    "users/{id}", 
    new { controller = "Users", action = "GetUser", id = UrlParameter.Optional} 
    new { id = @"\d+" } // Route constraint 
); 

如果你想使用URL设置控制器和动作自动调用你会需要像

routes.MapRoute(
     "GetUser", 
     "{controller}/{action}/{id}", 
     new { id = UrlParameter.Optional} 
     new { id = @"\d+" } // Route constraint 
    ); 

这将调用一个方法GetUser(int? id)

但这需要你更改你想要的网址/users/getuser/1234将去GetUser(int id)/users/getallusers将去GetAllUsers()。这是未经测试的方式 - 可能会有一些轻微的错误。