自定义控制器名称空间

时间:2013-03-25 16:20:19

标签: asp.net-mvc asp.net-mvc-routing

我正在将现有的应用程序从ASP.NET webforms移动到ASP.NET MVC。

在admin目录和公共目录下都存在一些页面名称,例如/ help /以及/ admin / help /

命名空间与目录结构匹配,因此/ help页面将位于MyApplication.Help中,而/ admin / help将位于MyApplication.Admin.Help中。我想保留控制器的设置,所以理想情况下我想要MyApplication.Help.HelpController和MyApplication.Admin.Help.HelpController。

我已经设置了这样的路线

    routes.MapRoute(
      "Admin",
        // Route name
      "admin/{controller}/{action}/{id}",
        // URL with parameters
      new { controller = "Home", action = "Index", id = "" },
        // Parameter defaults
    new []{"MyApplication.Admin.*"}
        //namespaces to find controller in
    ).DataTokens["UseNamespaceFallback"] = false;

    routes.MapRoute(
      "Default",
        // Route name
      "{controller}/{action}/{id}",
        // URL with parameters
      new { controller = "Home", action = "Index", id = "" },
        // Parameter defaults
    new [] { "MyApplication.*" }
        //namespaces to find controller in
    ).DataTokens["UseNamespaceFallback"] = false;

使用此设置,/ admin / help路由正常,但/ help路由失败,抱怨多个类型匹配名为“help”的控制器(因为MyApplication.Help.HelpController和MyApplication.Admin.Help.HelpController显然与我给出的MyApplication。*命名空间相匹配。

是否可以

  1. 设置两条路线的名称空间,以便第二条路线与“除管理员之外的任何东西”相匹配

  2. 设置两条路线的名称空间,以便第二条路线只有当有一层文件夹而不是两层时才匹配,或者

  3. 编写一个自定义方法,告诉路由为控制器查找什么命名空间(所以我可以自己实现这个逻辑)?
  4. 不幸的是,更改文件夹层次结构(例如将所有非管理页面放在“公共”文件夹/命名空间下)不是一个选项(因为我正在逐步移动到MVC,因此一些页面仍然作为webforms提供)。

1 个答案:

答案 0 :(得分:1)

所以这就是我最终做的事情,至少现在如此。对于非管理员路由,我创建了一个方法,该方法将列出所有适当的命名空间,并在应用程序启动时将其注册到路由。据推测,这在某种程度上减慢了应用程序启动速度,但我无法察觉到差异。

如果有人有更好的方法,我很高兴听到它。

routes.MapRoute(
  "Admin",
    // Route name
  "admin/{controller}/{action}/{id}",
    // URL with parameters
  new { controller = "Home", action = "Index", id = "" },
    // Parameter defaults
new []{"MyApplication.Admin.*"}
    //namespaces to find controller in
).DataTokens["UseNamespaceFallback"] = false;

routes.MapRoute(
  "Default",
    // Route name
  "{controller}/{action}/{id}",
    // URL with parameters
  new { controller = "Home", action = "Index", id = "" },
    // Parameter defaults
GetNonAdminNamespaces()
    //namespaces to find controller in
).DataTokens["UseNamespaceFallback"] = false;


  private static string[] GetNonAdminNamespaces()
  {
      var namespaces = new HashSet<string>();
      System.Type[] allTypes =  Assembly.GetCallingAssembly().GetTypes();
      foreach (var item in allTypes)
      {
          string ns = item.Namespace;
          if ( !string.IsNullOrEmpty(ns) && ns.StartsWith("MyApplication.") && !ns.StartsWith("MyApplication.Admin."))
          {
              namespaces.Add(ns);
          }
      }
      return namespaces.ToArray();
  }
相关问题