【发布时间】:2012-11-29 04:10:22
【问题描述】:
我用 ninject for MVC 为自己制作了一个模块化框架。
每个模块都可以注册自己的路由并包含自己的视图。
模块目录(dll 位置):~/Modules/<module name>/
模块视图位于内部:<Module dir>/Views/
它们的排列方式与普通的 mvc 应用程序完全相同,IE 每个控制器都有一个文件夹和一个共享文件夹。
我想渲染一个带有布局的视图,但是我希望布局位置由核心框架设置(以便我可以更改主题)。
我有一个具有layout = _layout.cshtml 的视图,当我运行应用程序时它返回:
The layout page "_Layout.cshtml" could not be found at the following path: "~/Modules/Module2/Views/Home/_Layout.cshtml".
被调用的视图在这里~/Modules/Module2/Views/Home/Index.cshtml。但我希望它在另一个位置寻找布局而不是在每个视图中设置它。无论如何我可以在核心框架中做到这一点吗?请注意,我将它设置为 MasterLocationFormats 以查看共享,它显然没有(我通过在其中放置 _layout.cshtml 进行了测试)。
自定义视图引擎:
public NinjectRazorViewEngine(): base()
{
ViewLocationFormats = new[] {
"~/Modules/%1/Views/{1}/{0}.cshtml",
"~/Modules/%1/Views/{1}/{0}.vbhtml",
"~/Modules/%1/Views/Shared/{0}.cshtml",
"~/Modules/%1/Views/Shared/{0}.vbhtml"
};
MasterLocationFormats = new[] {
"~/Modules/%1/Views/{1}/{0}.cshtml",
"~/Modules/%1/Views/{1}/{0}.vbhtml",
"~/Modules/%1/Views/Shared/{0}.cshtml",
"~/Modules/%1/Views/Shared/{0}.vbhtml",
};
PartialViewLocationFormats = new[] {
"~/Modules/%1/Views/{1}/{0}.cshtml",
"~/Modules/%1/Views/{1}/{0}.vbhtml",
"~/Modules/%1/Views/Shared/{0}.cshtml",
"~/Modules/%1/Views/Shared/{0}.vbhtml"
};
PartialViewLocationFormats = ViewLocationFormats;
AreaPartialViewLocationFormats = AreaViewLocationFormats;
}
protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
object moduleName;
if(controllerContext.RequestContext.RouteData.Values.TryGetValue("module",out moduleName))
return base.CreatePartialView(controllerContext, partialPath.Replace("%1", (string)moduleName));
return base.CreatePartialView(controllerContext, partialPath);
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
object moduleName;
if (controllerContext.RequestContext.RouteData.Values.TryGetValue("module", out moduleName))
return base.CreateView(controllerContext, viewPath.Replace("%1", (string)moduleName), masterPath.Replace("%1", (string)moduleName));
return base.CreateView(controllerContext, viewPath, masterPath);
}
protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
{
object moduleName;
if (controllerContext.RequestContext.RouteData.Values.TryGetValue("module", out moduleName))
return base.FileExists(controllerContext, virtualPath.Replace("%1", (string)moduleName));
return base.FileExists(controllerContext, virtualPath);
}
【问题讨论】:
-
模块是如何实现的?它们是作为 MVC 区域实现的吗?
-
它们本质上是向内核注册控制器和其他任何东西的 ninject 模块。自定义控制器工厂通过内核查找控制器。每个模块都存在于一个单独的程序集中。
-
您解决了吗?我目前遇到了同样的问题。
-
是的,我现在就发布代码
-
@ngm 我已经发布了答案。
标签: c# .net asp.net-mvc razor asp.net-mvc-4