asp.net-mvc-2 - 获取与 MVC 项目关联的区域

标签 asp.net-mvc-2 asp.net-mvc-areas

有没有办法可以获取 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/

相关文章:

asp.net-mvc-2 - ASP.NET MVC 2 将所有操作从一个 Controller 重定向到另一个 Controller

c# - 在 C# 中拆分字符串

c# - 检查删除一行是否安全

asp.net-mvc-2 - ASPNET MVC : ow can I make a page located in a given area (as opposed to the root structure) as default?

asp.net-mvc-3 - 使用 MVC 3 依赖注入(inject)和 Ninject 2.2 将全局操作过滤器绑定(bind)到区域中的所有 Controller

image - 将图像从 MVC Controller 渲染到屏幕

ASP.NET MVC - 单元测试,模拟 HttpContext 而不使用任何模拟框架

asp.net-mvc - 区域之间的 RedirectToAction?

asp.net - "No route in the route table matches the supplied values"使用区域时

asp.net-mvc-3 - 具有共享布局的 ASP.NET MVC 区域