有没有办法可以获取 MVC 项目中区域的名称?
以下是我能想到的几种方法:
a) 如果我有源,我可以浏览项目文件夹结构并枚举 Areas 文件夹下的文件夹。但这并不能保证所有文件夹都代表区域,除非我还列举了每个子文件夹下的 Controllers 和 Views 文件夹。如您所知,这种方法很糟糕。
b) 从二进制文件中,我可以枚举所有符合条件的命名空间 RootNamespaceOfProject.Areas.*
.
或者,我相信还有一种更优雅的方式。 ASP.NET MVC 框架中必须有一些字典来记录所有区域。
其次,在 MVC 框架中是否还有一个程序化的构造来代表一个区域?我似乎找不到一个。只有四种结构与区域相关:
1. AreaRegistration
2. AreaRegistrationContext
3. IRouteWithArea
4. AreaHelpers (an internal class)
如果有,是否有可能枚举该区域内的所有 Controller ?
已编辑
我刚刚注意到有一个名为
MVC-AreaRegistrationTypeCache.xml
的文件在文件夹\Windows\Microsoft.NET\Framework\v4.x.x\Temporary ASP.NET Files\root\RandomlyGeneratedHash1\RandomlyGeneratedHash2\UserCache 中。该文件夹有两个文件:
一) MVC-AreaRegistrationTypeCache.xml :该文件列出了机器上所有具有区域的组件中的所有区域。
b) MVC-ControllerTypeCache.xml :此文件列出了组件区域内的 Controller 。
现在,唯一需要确定的是是否有某种编程方式让 MVC 框架读取这些文件并告诉我二进制文件中是否存在某个区域。
我认为
AreaRegistration
类可能是一个。进一步探索它...
最佳答案
似乎您能够检索在项目中注册的路由的唯一方法是枚举项目中继承 AreaRegistration 的类型,似乎没有任何对象私有(private)或公共(public)跟踪当前注册的区域。
长长的解释如下……
这里要记住的一个障碍是,区域只不过是任意字符串和命名空间列表之间的耦合。当一个区域被注册时,它只是扩展了应用程序的路由集合,其中包含一些可由唯一“区域”DataToken 识别的新规则。
如果看注册区域的流程,肯定是继承自System.Web.Mvc.AreaRegistration并覆盖 RegisterArea() . RegisterArea() 接收到 AreaRegistrationContext它定义了一个区域名称、路由集合和对象状态,但是如果您观察实现 RegisterArea() 的格式,它会返回 void 并且不做任何事情来保存上下文对象。更重要的是,如果您查看在 RegisterArea() 被触发(Reflector)之前运行的代码,您会看到传递给 RegisterArea() 的 AreaRegistrationContext 对象永远不会被永久跟踪。
internal static void RegisterAllAreas(RouteCollection routes, IBuildManager buildManager, object state)
{
foreach (Type type in TypeCacheUtil.GetFilteredTypesFromAssemblies("MVC-AreaRegistrationTypeCache.xml", new Predicate<Type>(AreaRegistration.IsAreaRegistrationType), buildManager))
{
((AreaRegistration) Activator.CreateInstance(type)).CreateContextAndRegister(routes, state);
}
}
internal void CreateContextAndRegister(RouteCollection routes, object state)
{
AreaRegistrationContext context = new AreaRegistrationContext(this.AreaName, routes, state);
string str = base.GetType().Namespace;
if (str != null)
{
context.Namespaces.Add(str + ".*");
}
this.RegisterArea(context);
}
如您所见,调用静态方法RegisterAllAreas()调用内部
RegisterAllAreas(RouteCollection routes, IBuildManager buildManager, object state)
,然后调用内部 CreateContextAndRegister(RouteCollection routes, object state)
,它创建 AreaRegistrationContext 并将其传递给 RegisterArea()
.据我所知,在任何时候,都不会为永久存储的每个区域创建 AreaRegistrationContext。
关于asp.net-mvc-2 - 获取与 MVC 项目关联的区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3619922/