【发布时间】:2013-01-31 20:30:00
【问题描述】:
我在解决我的 Asp.Net MVC 4 项目中的 404 响应时遇到问题。它内置于针对 4.5 的 VS2012。
我在独立的 DLL 中内置了预编译的视图和控制器。我能够动态加载 DLL 并从我的核心项目中检查它们,甚至调用它们的方法;但是,似乎 MVC 框架不知道控制器。我在这里很近,但缺少一些东西。
控制器和视图的背景
控制器构建在独立的 MVC 项目中,并继承自 Controller。那里没有什么太有趣的事情发生。视图使用 RazorGenerator 并成为项目中的类。
项目的输出是一个正确包含控制器和视图的 DLL。
DLL 实现了一个特定的接口,我们称之为IPlugin,在库中的一个单独的类(不是控制器的一部分)中。
加载 DLL
在 Visual Studio 中以管理员身份运行我编译了托管在 IIS 下的应用程序。构建项目后,我将插件 DLL 放入我的“插件”目录。没有调试(这在以后变得很重要),我打开 IE 并导航到该站点。 请注意,此时应用程序已构建,但从未运行,因此将触发启动事件。如果我回收应用程序池,这里的一切仍然是一致的。
我有一个Startup 类,它有两个方法PreStart 和PostStart,并分别使用WebActivator.PreApplicationStartMethod 和WebActivator.PostApplicationStartMethod 调用这些方法。
PreStart 是我执行以下操作的地方:
- 获取我的“插件”目录中所有插件 DLL 的列表
- 将所有插件复制到
AppDomain.CurrentDomain.DynamicDirectory - 加载类型...如果它包含
IPlugin然后- 将程序集添加到 BuildManager
- 在实现IPlugin的类上调用一些方法
在“PostStart”中,我编写了这段代码(基于来自 RazorGenerator.Mvc 的代码):
foreach (var assembly in Modules.Select(m=>m.Value))
{
var engine = new PrecompiledMvcEngine(assembly)
{
UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal
};
ViewEngines.Engines.Insert(0, engine);
VirtualPathFactoryManager.RegisterVirtualPathFactory(engine);
}
Modules 在此上下文中是一个键/值对,其中的值是加载的程序集。这段代码的目的是通过为每个知道如何解析视图的程序集添加一个视图引擎来确保 MVC 知道视图(这是 RazorGenerator 的一部分)。
我怎么知道我很接近(但显然缺少雪茄)
IPlugin 定义了一个名为RegisterRoutes 的方法,您猜对了,路由将为实现该接口的人注册。我在PreStart 中调用此方法并添加路由 - 我已验证这些存在于我的路由表中。例如,在我的插件中定义的路由上,通过在PreStart 期间动态调用该方法创建,在检查我的路由时,我看到类似这样的数据令牌:
Namespaces = Plugin.Name.Controllers
所以,路由已注册,程序集已加载,我已验证 DLL 已正确复制到 AppDomain 的 DynamicDirectory。我能够调用在运行时动态加载的类的成员。但是当我导航到与路由匹配的 URL 时,我得到了 404。这不是“找不到视图”的 YSOD,更像是根本找不到控制器。
这是让我感到困惑的部分:如果此时我什么都不做,返回 Visual Studio 并按 F5...一切正常。
就像 Visual Studio 以某种我无法识别的方式意识到控制器,而 MVC 框架正在接受它。
最后一个问题
我缺少什么,如何让 MVC 框架了解我的控制器?
嘿,在这一点上,如果你还在读这篇文章,谢谢。 :)
【问题讨论】:
-
1. VS 是否使用 Cassini 运行?尝试将其更改为 IIS Express 并检查它是否继续正常运行。 2. 尝试安装RouteDebugger - 也许它可能会给你一些关于路由是否在IIS下正确注册的线索
-
感谢@Pranav,但它已经在 IIS 上。路由调试器显示路由正在运行。
-
这可能是个问题吗? stackoverflow.com/questions/14971895/…
-
+1,但不,还没有,反正。框架没有找到控制器,所以还没有任何东西在寻找视图。而且,当我重新编译时,一切正常。
标签: .net asp.net-mvc asp.net-mvc-4 assemblies