我们有一个 ASP.NET MVC 4 应用程序,其中包含大约 3000 个 View 。我们决定将这组 View 拆分为单独的 DLL,并使用 RazorGenerator 对其进行编译。我们在主 MVC 项目中只保留主 _Layout.cshtml 和相关文件。
我们无法从 DLL 中加载部分 View 以及主 MVC 项目中的主 View 。详细说明如下。
已经完成的:
.
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
// ...
// some code determining whether we've got an assembly with views
// ...
var engine = new PrecompiledMvcEngine(assembly);
engine.UsePhysicalViewsIfNewer = true;
ViewEngines.Engines.Insert(0, engine);
// StartPage lookups are done by WebPages.
VirtualPathFactoryManager.RegisterVirtualPathFactory(engine);
}
什么不起作用:
我无法加载在主 MVC 项目(例如 _Layout.cshtml)中定义的 View 以及在其中一个库(例如 Partial.cshtml)中定义的部分 View 。我在 Controller 的操作中使用以下代码来告诉 MVC 框架我请求哪个 View :
var view = "~/Views/" + partialName + ".cshtml";
return View(view, "~/Views/Shared/_Layout.cshtml", model);
错误消息说:
未找到 View “~/Views/Partial.cshtml”或其母版,或者没有 View 引擎支持搜索的位置。搜索了以下位置:
~/Views/Partial.cshtml
~/Views/Shared/_Layout.cshtml
当我尝试通过指定以下任一项来单独加载 View 时:
return View("~/Views/Shared/_Layout.cshtml", model);
或者
return View(view, model);
,找到了正确的观点。但是我需要将它们一起加载。当我在主 MVC 项目中拥有所有必需的 .cshtml 文件时,代码工作。
请注意,已编译 DLL 中的 View 具有与 Controller 操作中指定的路径相同的 PageVirtualPathAttribute,例如:
namespace SomeBaseNamespace.Views
{
[GeneratedCode("RazorGenerator", "1.5.0.0"), PageVirtualPath("~/Views/Partial.cshtml")]
public class Partial : WebViewPage<PartialModel>
{
[CompilerGenerated]
private static class <Execute>o__SiteContainer3
{
// logic
}
public override void Execute()
{
// logic
}
}
}
综上所述,问题是如何用另一个项目中定义的部分编译 View 调用存储在主MVC项目中的主 View ?
最佳答案
在应用程序启动时,当您的应用程序调用此行时...
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
包含外部 View 的程序集可能尚未加载,因此未包含在 View 引擎中。我实际上建议不要使用
AppDomain.CurrentDomain.GetAssemblies()
无论如何,因为这将包括启动时加载的所有程序集。解决方法是添加RazorGenerator.Mvc NuGet 打包到每个包含编译 View 的项目。这将以与您类似的方式添加以下应用程序启动代码...
[assembly: WebActivatorEx.PostApplicationStartMethod(typeof(SomeBaseNamespace.Views.RazorGeneratorMvcStart), "Start")]
namespace SomeBaseNamespace.Views
{
public static class RazorGeneratorMvcStart
{
public static void Start()
{
var engine = new PrecompiledMvcEngine(typeof(RazorGeneratorMvcStart).Assembly)
{
UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal
};
ViewEngines.Engines.Insert(0, engine);
}
}
}
请注意这如何使用当前程序集(您的 View 程序集)创建 View 引擎并将其添加到静态
ViewEngines
集合(包含在主 MVC 项目中)。一旦投入生产,我还建议关闭
UsePhysicalViewsIfNewer
设置,这增加了显着的性能开销。
关于 Razor 发电机 : how to use view compiled in a library as the partial view for master defined in main mvc project,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13527354/