ASP.NET MVC中单独程序集中的视图

我正在尝试创建一个Web应用程序,希望能够在其中插入单独的程序集。我将MVC Preview 4与Unity结合使用进行依赖项注入,我使用它从插件程序集创建控制器。我正在使用WebForms(默认aspx)作为视图引擎。

如果要使用视图,则由于ASPX部件的动态编译,我将停留在核心项目中定义的视图上。我正在寻找一种将ASPX文件封装在不同程序集中的正确方法,而不必执行整个部署步骤。我是否缺少明显的东西?还是我应该以编程方式创建视图?


更新:我更改了接受的答案。即使Dale的答案很彻底,我还是选择了其他虚拟路径提供程序来寻求解决方案。我觉得它像一个咒语一样工作,只占用大约20行代码。


偶然的你
浏览 420回答 3
3回答

慕村225694

我花了很长时间才能从各个部分样本中正常工作,所以这里是从共享库中的Views文件夹获取视图所需的全部代码,该库与常规Views文件夹的结构相同,但所有内容都设置为嵌入式构建资源。如果普通文件不存在,它将仅使用嵌入式文件。Application_Start的第一行:HostingEnvironment.RegisterVirtualPathProvider(new EmbeddedViewPathProvider());虚拟路径提供者&nbsp; &nbsp;public class EmbeddedVirtualFile : VirtualFile{&nbsp; &nbsp; public EmbeddedVirtualFile(string virtualPath)&nbsp; &nbsp; &nbsp; &nbsp; : base(virtualPath)&nbsp; &nbsp; {&nbsp; &nbsp; }&nbsp; &nbsp; internal static string GetResourceName(string virtualPath)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (!virtualPath.Contains("/Views/"))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; var resourcename = virtualPath&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Substring(virtualPath.IndexOf("Views/"))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Replace("Views/", "OrangeGuava.Common.Views.")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Replace("/", ".");&nbsp; &nbsp; &nbsp; &nbsp; return resourcename;&nbsp; &nbsp; }&nbsp; &nbsp; public override Stream Open()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Assembly assembly = Assembly.GetExecutingAssembly();&nbsp; &nbsp; &nbsp; &nbsp; var resourcename = GetResourceName(this.VirtualPath);&nbsp; &nbsp; &nbsp; &nbsp; return assembly.GetManifestResourceStream(resourcename);&nbsp; &nbsp; }}public class EmbeddedViewPathProvider : VirtualPathProvider{&nbsp; &nbsp; private bool ResourceFileExists(string virtualPath)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Assembly assembly = Assembly.GetExecutingAssembly();&nbsp; &nbsp; &nbsp; &nbsp; var resourcename = EmbeddedVirtualFile.GetResourceName(virtualPath);&nbsp; &nbsp; &nbsp; &nbsp; var result = resourcename != null && assembly.GetManifestResourceNames().Contains(resourcename);&nbsp; &nbsp; &nbsp; &nbsp; return result;&nbsp; &nbsp; }&nbsp; &nbsp; public override bool FileExists(string virtualPath)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return base.FileExists(virtualPath) || ResourceFileExists(virtualPath);&nbsp; &nbsp; }&nbsp; &nbsp; public override VirtualFile GetFile(string virtualPath)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (!base.FileExists(virtualPath))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new EmbeddedVirtualFile(virtualPath);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return base.GetFile(virtualPath);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}使它工作的最后一步是,根Web.Config必须包含正确的设置才能解析强类型的MVC视图,因为不会使用views文件夹中的视图:<pages&nbsp; &nbsp; validateRequest="false"&nbsp; &nbsp; pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"&nbsp; &nbsp; pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"&nbsp; &nbsp; userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">&nbsp; <controls>&nbsp; &nbsp; <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />&nbsp; </controls></pages>要使其与Mono一起使用,还需要执行几个附加步骤。首先,您需要实现GetDirectory,因为views文件夹中的所有文件都是在应用启动时加载的,而不是根据需要加载的:public override VirtualDirectory GetDirectory(string virtualDir)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Log.LogInfo("GetDirectory - " + virtualDir);&nbsp; &nbsp; &nbsp; &nbsp; var b = base.GetDirectory(virtualDir);&nbsp; &nbsp; &nbsp; &nbsp; return new EmbeddedVirtualDirectory(virtualDir, b);&nbsp; &nbsp; }public class EmbeddedVirtualDirectory : VirtualDirectory{&nbsp; &nbsp; private VirtualDirectory FileDir { get; set; }&nbsp;&nbsp; &nbsp; public EmbeddedVirtualDirectory(string virtualPath, VirtualDirectory filedir)&nbsp; &nbsp; &nbsp; &nbsp; : base(virtualPath)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; FileDir = filedir;&nbsp; &nbsp; }&nbsp; &nbsp; public override System.Collections.IEnumerable Children&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get { return FileDir.Children; }&nbsp; &nbsp; }&nbsp; &nbsp; public override System.Collections.IEnumerable Directories&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get { return FileDir.Directories; }&nbsp; &nbsp; }&nbsp; &nbsp; public override System.Collections.IEnumerable Files&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!VirtualPath.Contains("/Views/") || VirtualPath.EndsWith("/Views/"))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return FileDir.Files;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var fl = new List<VirtualFile>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; foreach (VirtualFile f in FileDir.Files)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fl.Add(f);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var resourcename = VirtualPath.Substring(VirtualPath.IndexOf("Views/")).Replace("Views/", "OrangeGuava.Common.Views.").Replace("/", ".");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Assembly assembly = Assembly.GetExecutingAssembly();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var rfl = assembly.GetManifestResourceNames()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Where(s => s.StartsWith(resourcename))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Select(s => VirtualPath + s.Replace(resourcename, ""))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Select(s => new EmbeddedVirtualFile(s));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fl.AddRange(rfl);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return fl;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}最后,强类型视图将几乎但不是很完美。模型将被视为未类型化的对象,因此要进行强类型化输入,您需要使用类似以下内容来启动共享视图<% var Model2 = Model as IEnumerable<AppModel>;&nbsp; %>

人到中年有点甜

protected void Application_Start(){&nbsp; &nbsp; WebFormViewEngine engine = new WebFormViewEngine();&nbsp; &nbsp; engine.ViewLocationFormats = new[] { "~/bin/Views/{1}/{0}.aspx", "~/Views/Shared/{0}.aspx" };&nbsp; &nbsp; engine.PartialViewLocationFormats = engine.ViewLocationFormats;&nbsp; &nbsp; ViewEngines.Engines.Clear();&nbsp; &nbsp; ViewEngines.Engines.Add(engine);&nbsp; &nbsp; RegisterRoutes(RouteTable.Routes);}将视图的“复制到输出”属性设置为“始终复制”
打开App,查看更多内容
随时随地看视频慕课网APP