当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《ASP.NETMVC中单独程序集中的视图》经验,为你挑选了3个好方法。

我正在尝试创建一个web应用程序,我希望能够插入单独的程序集.我正在使用MVC预览4和Unity结合依赖注入,我用它来从我的插件程序集创建控制器.我正在使用WebForms(默认的aspx)作为我的视图引擎.

如果我想使用一个视图,我会坚持核心项目中定义的视图,因为ASPX部分的动态编译.我正在寻找一种将ASPX文件封装在不同程序集中的正确方法,而无需完成整个部署步骤.我错过了一些明显的东西吗 或者我应该以编程方式创建我的观点?


更新:我改变了接受的答案.尽管戴尔的答案非常彻底,但我还是选择了不同的虚拟路径提供商.它的工作方式就像一个魅力,我认为完全只需要20行代码.



1> Tom Clarkson..:

我花了太长时间才能从各种部分样本中正常工作,所以这里是从共享库中的Views文件夹获取视图所需的完整代码,其结构与常规Views文件夹相同,但所有内容都设置为嵌入式构建资源.如果通常的文件不存在,它将只使用嵌入的文件.

Application_Start的第一行:

HostingEnvironment.RegisterVirtualPathProvider(new EmbeddedViewPathProvider());

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视图的正确设置,因为将不使用views文件夹中的那个:


  
    
  

要使其与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();

            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;  %>


记住将构建操作设置为视图的"嵌入式资源"也很重要.视图的文件夹也应存在于Web项目中.在我的例子中,我将视图放在程序集项目的文件夹Views/Shared/Dynamic.cshtml中,并且必须在引用程序集的web项目中创建Views/Shared.

2> Joseph Kingr..:

基本上这与人们使用WebForms并尝试将其UserControl ASCX文件编译为DLL的问题相同.我发现这个http://www.codeproject.com/KB/aspnet/ASP2UserControlLibrary.aspx也可能对你有用.



3> 小智..:
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);
}

将视图的"复制到输出"属性设置为"始终复制"

推荐阅读
pan2502851807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有