【发布时间】:2011-06-15 14:36:25
【问题描述】:
我想将我的控制器和视图拆分为单独的类库,以便它们可以在多个 ASP.NET MVC 3 应用程序中重用。使用单独的程序集时,控制器部分不是问题,但是让视图引擎定位视图是。
我最终使用了Compile your asp.net mvc Razor views into a seperate dll。
有没有我错过的更简单的方法?
【问题讨论】:
标签: asp.net-mvc-3 razor
我想将我的控制器和视图拆分为单独的类库,以便它们可以在多个 ASP.NET MVC 3 应用程序中重用。使用单独的程序集时,控制器部分不是问题,但是让视图引擎定位视图是。
我最终使用了Compile your asp.net mvc Razor views into a seperate dll。
有没有我错过的更简单的方法?
【问题讨论】:
标签: asp.net-mvc-3 razor
我已经修改了 here 发布的想法,以使用 MVC3。这非常快速和容易。唯一的小缺点是共享视图需要嵌入资源,因此需要编译。
将您的共享视图(.cshtml、.vbhtml 文件)放入库项目中。 (我在这个项目中也有一些共享控制器。)如果你想在你的应用程序中使用 _Layout.cshtml,请确保在你的共享视图中包含一个指向它的 _ViewStart.cshtml。
在库项目中,将所有视图的 Build Action 属性设置为 Embedded Resource。
在库项目中添加以下代码,将视图的内容写入 tmp/Views 目录。
.
public class EmbeddedResourceViewEngine : RazorViewEngine
{
public EmbeddedResourceViewEngine()
{
ViewLocationFormats = new[] {
"~/Views/{1}/{0}.aspx",
"~/Views/{1}/{0}.ascx",
"~/Views/Shared/{0}.aspx",
"~/Views/Shared/{0}.ascx",
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml",
"~/tmp/Views/{0}.cshtml",
"~/tmp/Views/{0}.vbhtml"
};
PartialViewLocationFormats = ViewLocationFormats;
DumpOutViews();
}
private static void DumpOutViews()
{
IEnumerable<string> resources = typeof(EmbeddedResourceViewEngine).Assembly.GetManifestResourceNames().Where(name => name.EndsWith(".cshtml"));
foreach (string res in resources) { DumpOutView(res); }
}
private static void DumpOutView(string res)
{
string rootPath = HttpContext.Current.Server.MapPath("~/tmp/Views/");
if (!Directory.Exists(rootPath))
{
Directory.CreateDirectory(rootPath);
}
Stream resStream = typeof(EmbeddedResourceViewEngine).Assembly.GetManifestResourceStream(res);
int lastSeparatorIdx = res.LastIndexOf('.');
string extension = res.Substring(lastSeparatorIdx + 1);
res = res.Substring(0, lastSeparatorIdx);
lastSeparatorIdx = res.LastIndexOf('.');
string fileName = res.Substring(lastSeparatorIdx + 1);
Util.SaveStreamToFile(rootPath + fileName + "." + extension, resStream);
}
}
我正在使用 Adrian 的 StreamToFile 编写器,找到 here。
.
public static void RegisterCustomViewEngines(ViewEngineCollection viewEngines)
{
//viewEngines.Clear(); //This seemed like a bad idea to me.
viewEngines.Add(new EmbeddedResourceViewEngine());
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
RegisterCustomViewEngines(ViewEngines.Engines);
}
【讨论】:
看看 mvc contrib 的可移植区域: http://www.lostechies.com/blogs/hex/archive/2009/11/01/asp-net-mvc-portable-areas-via-mvccontrib.aspx 它们是专门为此目的而制造的。如果你走这条路,你需要维护的代码就更少了;-)
【讨论】:
只是对 Carson Herrick 的优秀帖子的一些补充...
您需要解析一些引用(您需要将System.Runtime.Remoting 包含到您的项目中)。
Utils.SaveStreamToFile需要改为->
System.Runtime.Remoting.MetadataServices.MetaData.SaveStreamToFile(resStream, rootPath + fileName + "." + extension);
您可能会收到错误消息 - 视图必须派生自 WebViewPage 或 WebViewPage<TModel>。答案就在这里:The view must derive from WebViewPage, or WebViewPage<TModel>
部署项目时,加载项目时很可能会出错。您需要授予您正在使用的 APP POOL 对该文件夹的(完全)权限。
【讨论】: