2008-09-04 110 views
3

我正在寻找一些示例或路由的示例,以用于以下类型的场景:MVC路由中控制器的类别? (在独立命名空间中复制控制器名称)

做事情的一般示例是:{controller}/{action}/{id }

所以在做一个商店产品搜索的情况下,你就必须:

public class ProductsController: Controller 
{ 
    public ActionResult Search(string id) // id being the search string 
    { ... } 
} 

假设您有几家商店做到这一点,你想,始终是有什么办法可以再有:{category}/{controller}/{action}/{id}

因此,您可以针对特定商店进行特定搜索,但是针对不同的商店使用不同的搜索方法?

(如果需要的店名比函数本身的网址更高的优先级)

或将它归结为:

public class ProductsController: Controller 
{ 
    public ActionResult Search(int category, string id) // id being the search string 
    { 
     if(category == 1) return Category1Search(); 
     if(category == 2) return Category2Search(); 
     ... 
    } 
} 

它可能不是一个很好的例子,但基本上这个想法是使用相同的控制器名称,因此在几种不同的情况下都有一个简单的URL,或者您是否需要唯一的控制器名称,并且没有办法将它们放在稍微不同的名称空间/目录中?

编辑补充:

其他原因,我想这是因为我可能要具有类别的URL,并且某些控制器将只在某些类别的工作。

IE:

/本/搜索/项目/搜索+长期< - 工程

/是/搜索/项目/搜索+长期< - 将无法正常工作 - 因为搜索控制器是不允许的。

+0

1.0版本中的“区域”概念是否解决了这个问题? – hometoast 2009-06-01 01:10:30

回答

1

没有任何妥协的最好方法就是通过继承IControllerFactory来实现自己的ControllerFactory。您将实现的CreateController方法处理创建控制器实例以处理RouteHandler和ControllerActionInvoker的请求。约定是在创建控制器时使用控制器的名称,因此您需要重写此功能。这将是您放置自定义逻辑以基于路由创建控制器的位置,因为您将拥有多个具有相同名称但位于不同文件夹中的控制器。然后,您将需要在应用程序启动时注册您的自定义控制器工厂,就像您的路线一样。

您需要考虑的另一个方面是在创建控制器时查找您的视图。如果您打算为所有人使用相同的视图,那么您不应该做与使用的约定不同的任何事情。如果您还计划组织您的视图,则还需要创建自己的ViewLocator,并在控制器工厂中创建它时将其分配给控制器。

为了了解代码,我已经回答了几个与这个问题有关的问题,但是这个问题在某种程度上是不同的,因为控制器名称是相同的。我收录了供参考的链接。

另一条路线,但可能需要一些妥协将使用新的AcceptVerbs属性。查看question了解更多详情。我还没有玩过这个新功能,但它可能是另一条路线。

4

我甚至发现它甚至没有通过搜索,而是通过扫描通过this question的ASP .NET论坛。

利用这一点,你可以有相同名称的控制器下的命名空间的任何部分,只要您符合哪些路由属于哪一个命名空间(你可以为每个路由多个命名空间,如果你需要的!)

但是从这里开始,你可以放在你的控制器下的一个目录下,所以如果你的控制器是“MyWebShop.Controllers”,你可以放一个“Shop1”目录,命名空间为“MyWebShop.Controllers.Shop1”

Then this Works:

public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     var shop1namespace = new RouteValueDictionary(); 
     shop1namespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers.Shop1" 
     })); 

     routes.Add("Shop1", new Route("Shop1/{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new 
      { 
       action = "Index", 
       id = (string)null 
      }), 
      DataTokens = shop1namespace 
     }); 

     var shop2namespace = new RouteValueDictionary(); 
     shop2namespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers.Shop2" 
     })); 

     routes.Add("Shop2", new Route("Shop2/{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new 
      { 
       action = "Index", 
       id = (string)null 
      }), 
      DataTokens = shop2namespace 
     }); 

     var defaultnamespace = new RouteValueDictionary(); 
     defaultnamespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers" 
     })); 

     routes.Add("Default", new Route("{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }), 
      DataTokens = defaultnamespace    
     }); 
    } 

唯一的另一件事是它将引用仍在基本目录中的视图,因此如果将视图放入目录以匹配,则必须在将视图名称返回到控制器内时将其放入视图名称中。

相关问题