控制器在单独的组装和路由
在相同的解决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的行为,则进行所有必要的更改并不重要;)