控制器在单独的组装和路由

在相同的解决scheme中,有一个ASP.NET MVC4应用程序Slick.App和类库Awesome.Mvc.Lib 。 Awesome.Mvc.Lib包含一个控制器类。

 public class ShinnyController : Controller { [HttpGet] public string Index() { return "Hello, from Awesome.Mvc.Lib"; } } 

如果我只是将Slick.App的引用添加到Awesome.Mvc.Lib,运行应用程序并将浏览器指向/shinny shinny,实际上我会看到响应“Hello,from Awesome.Mvc.Lib”。

这是我所不希望的。 我一直认为ASP.NET MVC尊重控制器所在的命名空间。所以,来自其他命名空间的控制器不会暴露,至less在我没有要求之前。

我试图改变默认的路由注册,使用namespaces参数。

  routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, namespaces: new [] { "Slick.App.Controllers" } ); 

不过,ShinnyController路线仍然匹配'/ shinny'。

我有一个担心,这是正确的默认行为。 我的问题是,如何明确地说出哪些控制器是公开的,并防止默认路由匹配单独的类库中的控制器?

路由上的命名空间列表仅给予某些命名空间优先于其他命名空间,这些命名空间并未列出:

 new [] {"Namespace1", "Namespace2"} 

Namespace1并没有给予更高的优先级,而只是对两个命名空间优先于其他命名空间。

这意味着列表中的命名空间首先被search到控制器,然后,如果没有find匹配,则使用具有该名称的可用控制器的其余部分。

您可以通过执行以下操作来禁止使用非优先级控制器:

 var myRoute = routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, namespaces: new [] { "Slick.App.Controllers" } ); myRoute.DataTokens["UseNamespaceFallback"] = false; 

你可以像这样inheritanceDefaultControllerFactory:

 public class CustomControllerFactory : DefaultControllerFactory { protected override Type GetControllerType(System.Web.Routing.RequestContext requestContext, string controllerName) { var type = base.GetControllerType(requestContext, controllerName); if (type != null && IsIngored(type)) { return null; } return type; } public static bool IsIngored(Type type) { return type.Assembly.GetCustomAttributes(typeof(IgnoreAssemblyAttribute), false).Any() || type.GetCustomAttributes(typeof(IgnoreControllerAttribute), false).Any(); } } 

然后对Global.asax进行一些更改

  protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory()); } 

而你在这里! 任何标有IgnoreControllerAttribute的types都将不可见。 你甚至可以隐藏整个组件。

如果您需要一些基于configuration的行为,则进行所有必要的更改并不重要;)