我正在尝试创建一个where应用程序,我希望能够在其中插入独立的程序集。我正在使用MVC预览版4结合Unity进行依赖注入,我用它来从我的插件程序集创建控制器。我使用WebForms (默认的aspx)作为我的视图引擎。
如果我想使用视图,我会被困在核心项目中定义的视图上,因为ASPX部件的动态编译。我正在寻找一种合适的方法来将ASPX文件封装在不同的程序集中,而不必经历整个部署步骤。我是不是漏掉了什么明显的东西?或者我应该求助于以编程方式创建我的视图?
更新:我更改了被接受的答案。尽管戴尔的回答非常透彻,但我还是选择了不同的虚拟路径提供商作为解决方案。它的工作方式就像一个护身符,我认为总共只需要20行代码。
发布于 2008-08-29 20:34:49
本质上,这与人们在使用WebForms并试图将他们的UserControl ASCX文件编译成DLL时遇到的问题是相同的。我找到了这个http://www.codeproject.com/KB/aspnet/ASP2UserControlLibrary.aspx,它可能也适用于你。
发布于 2011-01-01 18:59:13
我花了很长时间才从不同的部分样本中得到正确的工作,所以这里是从共享库中的视图文件夹中获取视图所需的完整代码,其结构与常规视图文件夹相同,但所有内容都设置为嵌入式资源。如果通常的文件不存在,它将只使用嵌入的文件。
Application_Start的第一行:
HostingEnvironment.RegisterVirtualPathProvider(new EmbeddedViewPathProvider());
The VirtualPathProvider
public class EmbeddedVirtualFile : VirtualFile
{
public EmbeddedVirtualFile(string virtualPath)
: base(virtualPath)
{
}
internal static string GetResourceName(string virtualPath)
{
if (!virtualPath.Contains("/Views/"))
{
return null;
}
var resourcename = virtualPath
.Substring(virtualPath.IndexOf("Views/"))
.Replace("Views/", "OrangeGuava.Common.Views.")
.Replace("/", ".");
return resourcename;
}
public override Stream Open()
{
Assembly assembly = Assembly.GetExecutingAssembly();
var resourcename = GetResourceName(this.VirtualPath);
return assembly.GetManifestResourceStream(resourcename);
}
}
public class EmbeddedViewPathProvider : VirtualPathProvider
{
private bool ResourceFileExists(string virtualPath)
{
Assembly assembly = Assembly.GetExecutingAssembly();
var resourcename = EmbeddedVirtualFile.GetResourceName(virtualPath);
var result = resourcename != null && assembly.GetManifestResourceNames().Contains(resourcename);
return result;
}
public override bool FileExists(string virtualPath)
{
return base.FileExists(virtualPath) || ResourceFileExists(virtualPath);
}
public override VirtualFile GetFile(string virtualPath)
{
if (!base.FileExists(virtualPath))
{
return new EmbeddedVirtualFile(virtualPath);
}
else
{
return base.GetFile(virtualPath);
}
}
}
让它工作的最后一步是根Web.Config必须包含正确的设置来解析强类型的MVC视图,因为视图文件夹中的视图将不会被使用:
<pages
validateRequest="false"
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<controls>
<add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
</controls>
</pages>
要让它与Mono一起工作,还需要几个额外的步骤。首先,您需要实现GetDirectory,因为views文件夹中的所有文件都在应用程序启动时加载,而不是在需要时加载:
public override VirtualDirectory GetDirectory(string virtualDir)
{
Log.LogInfo("GetDirectory - " + virtualDir);
var b = base.GetDirectory(virtualDir);
return new EmbeddedVirtualDirectory(virtualDir, b);
}
public class EmbeddedVirtualDirectory : VirtualDirectory
{
private VirtualDirectory FileDir { get; set; }
public EmbeddedVirtualDirectory(string virtualPath, VirtualDirectory filedir)
: base(virtualPath)
{
FileDir = filedir;
}
public override System.Collections.IEnumerable Children
{
get { return FileDir.Children; }
}
public override System.Collections.IEnumerable Directories
{
get { return FileDir.Directories; }
}
public override System.Collections.IEnumerable Files
{
get {
if (!VirtualPath.Contains("/Views/") || VirtualPath.EndsWith("/Views/"))
{
return FileDir.Files;
}
var fl = new List<VirtualFile>();
foreach (VirtualFile f in FileDir.Files)
{
fl.Add(f);
}
var resourcename = VirtualPath.Substring(VirtualPath.IndexOf("Views/"))
.Replace("Views/", "OrangeGuava.Common.Views.")
.Replace("/", ".");
Assembly assembly = Assembly.GetExecutingAssembly();
var rfl = assembly.GetManifestResourceNames()
.Where(s => s.StartsWith(resourcename))
.Select(s => VirtualPath + s.Replace(resourcename, ""))
.Select(s => new EmbeddedVirtualFile(s));
fl.AddRange(rfl);
return fl;
}
}
}
最后,强类型视图几乎但不能完美地工作。模型将被视为非类型化对象,因此要重新获得强类型,您需要从以下内容开始共享视图
<% var Model2 = Model as IEnumerable<AppModel>; %>
发布于 2009-10-03 20:29:32
protected void Application_Start()
{
WebFormViewEngine engine = new WebFormViewEngine();
engine.ViewLocationFormats = new[] { "~/bin/Views/{1}/{0}.aspx", "~/Views/Shared/{0}.aspx" };
engine.PartialViewLocationFormats = engine.ViewLocationFormats;
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(engine);
RegisterRoutes(RouteTable.Routes);
}
将视图的“复制到输出”属性设置为“始终复制”
https://stackoverflow.com/questions/19746
复制相似问题