`
cloudtech
  • 浏览: 4594554 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

ASP.NET读取DLL文件中的页面和用户控件(VirtualPathProvider VirtualFile)

 
阅读更多
这篇文章用来介绍一下如何通过VirtualPathProvider来获取程序集中的页面和用户控件的内容。这样做的好处是可以在项目中达到所有的文件路径是统一的,不管你的页面或者控件来自于任何一个程序集。

举个例子,你的项目中所有的aspx页面均存放在Website这个目录下,那么通常你可以使用相对路径~/WebSite/WebPage.aspx来找到目录下的WebPage页面。

当你需要从某个程序集(DLL)中加载一个page到你的页面上来。通常情况下必须要使用Assembly.load()方法来找到它,并且很有可能需要使用到反射来确定它的类型,并且将他返回给页面,但是当你使用VirtualFile和VirtualPathProvider的时候,这时候对于父页面来说,它只需要去读取这个custom file的虚拟路径即可,具体返回的stream由你自己来定义(例如你仍然可以使用Assembly.load来获取文件)。那么你可以自定义它的路径来保证路径的一致性。

举个例子来看看如何来实现这个功能,能够更清晰一些。

准备工作是建一个Web应用程序,创建一个页面WebPage和一个用户控件WebUserControl,同理新建一个另外一个项目也包含同名的这两个文件,当然你最好在页面上区分它们来自本项目还是其他项目。例如本项目的写“I am from 本项目名”,其他项目则改为其他项目的名字。

[本示例完整源码下载(0分)] http://download.csdn.net/detail/aa466564931/4414671

首先我们创建一个CustomFile继承自VirtualFile,这个类的作用是加载来自其他程序集的文件并且返回给VirtualFileProvider使用:

    public class CustomFile: VirtualFile
    {
        string path
        {
            get;
            set;
        }

        public CustomFile(string virtualPath)
            : base(virtualPath)
        {
            path = VirtualPathUtility.ToAppRelative(virtualPath);
        }

        /// <summary>
        /// Override Open method to load resource files of assembly.
        /// </summary>
        /// <returns></returns>
        public override System.IO.Stream Open()
        {
            string[] strs = path.Split('/');
            string name = strs[2];
            string resourceName = strs[3];
            name = Path.Combine(HttpRuntime.BinDirectory, name);
            Assembly assembly = Assembly.LoadFile(name);
            if (assembly != null)
            {
                Stream s = assembly.GetManifestResourceStream(resourceName);
                return s;
            }
            else
            {
                return null;
            }
        }
    }


接着创建一个CustomVirtualProvider类继承自VirtualPathProvider,这里我们必须实现以下几个方法(Assembly是我自定义的文件名,你以为改为任意名称),注意AssemblyPathExist这个方法,在使用base.FileExists判断之前先进行我们的自定义路径的判断,如果存在则使用VirtualFile来取代默认的方法:

    public class CustomPathProvider : VirtualPathProvider
    {
        public CustomPathProvider()
        { 
        }

        /// <summary>
        /// Make a judgment that application find path contains specifical folder name.
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        private bool AssemblyPathExist(string path)
        {
            string relateivePath = VirtualPathUtility.ToAppRelative(path);
            return relateivePath.StartsWith("~/Assembly/", StringComparison.InvariantCultureIgnoreCase);
        }

        /// <summary>
        /// If we can find this virtual path, return true.
        /// </summary>
        /// <param name="virtualPath"></param>
        /// <returns></returns>
        public override bool FileExists(string virtualPath)
        {
            if (this.AssemblyPathExist(virtualPath))
            {
                return true;
            }
            else 
            {
                return base.FileExists(virtualPath);
            }
        }

        /// <summary>
        /// Use custom VirtualFile class to load assembly resources.
        /// </summary>
        /// <param name="virtualPath"></param>
        /// <returns></returns>
        public override VirtualFile GetFile(string virtualPath)
        {
            if (AssemblyPathExist(virtualPath))
            {
                return new CustomFile(virtualPath);
            }
            else
            {
                return base.GetFile(virtualPath);
            }
        }

        /// <summary>
        /// Return null when application use virtual file path.
        /// </summary>
        /// <param name="virtualPath"></param>
        /// <param name="virtualPathDependencies"></param>
        /// <param name="utcStart"></param>
        /// <returns></returns>
        public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart)
        {
            if (AssemblyPathExist(virtualPath))
            {
                return null;
            }
            else
            {
                return base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
            }
        }
    }

OK,接下来我们就可以使用我们自定义的path来加载程序集中的文件了,我们把一下代码放在default页面中:

注意~/WebSite/WebUserControl.ascx是本项目的文件,~/Assembly/CSASPNETAssembly.dll/CSASPNETAssembly.WebUserControl.ascx是来自于CSASPNETAssembly.dll的文件:

    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Add relative web pages and user controls in assembly and this application.
            DataTable tab = this.InitializeDataTable();
            if (tab != null && tab.Rows.Count != 0)
            {
                for (int i = 0; i < tab.Rows.Count; i++)
                {
                    Control control = Page.LoadControl(tab.Rows[i]["UserControlUrl"].ToString());
                    UserControl usercontrol = control as UserControl;
                    Page.Controls.Add(usercontrol);
                    HyperLink link = new HyperLink();
                    link.NavigateUrl = tab.Rows[i]["WebPageUrl"].ToString();
                    link.Text = tab.Rows[i]["WebPageText"].ToString();
                    Page.Controls.Add(link);
                }
            }
        }

        /// <summary>
        /// Initialize a DataTable variable for storing URL and text properties. 
        /// </summary>
        /// <returns></returns>
        protected DataTable InitializeDataTable()
        {
            DataTable tab = new DataTable();
            DataColumn userControlUrl = new DataColumn("UserControlUrl",Type.GetType("System.String"));
            tab.Columns.Add(userControlUrl);
            DataColumn webPageUrl = new DataColumn("WebPageUrl", Type.GetType("System.String"));
            tab.Columns.Add(webPageUrl);
            DataColumn webPageText = new DataColumn("WebPageText", Type.GetType("System.String"));
            tab.Columns.Add(webPageText);
            DataRow dr = tab.NewRow();
            dr["UserControlUrl"] = "~/Assembly/CSASPNETAssembly.dll/CSASPNETAssembly.WebUserControl.ascx";
            dr["WebPageUrl"] = "~/Assembly/CSASPNETAssembly.dll/CSASPNETAssembly.WebPage.aspx";
            dr["WebPageText"] = "Assembly/WebPage";
            DataRow drWebSite = tab.NewRow();
            drWebSite["UserControlUrl"] = "~/WebSite/WebUserControl.ascx";
            drWebSite["WebPageUrl"] = "~/WebSite/WebPage.aspx";
            drWebSite["WebPageText"] = "WebSite/WebPage";
            tab.Rows.Add(dr);
            tab.Rows.Add(drWebSite);
            return tab;
        }
    }


好了接下来你可以debug看下结果了。
分享到:
评论

相关推荐

    ASP.NET 控件的使用

    第一部分 构建ASP.NET页面 第1章 ASP.NET Framework概览 2 1.1 ASP.NET和.NET Framework 5 1.1.1 框架类库 5 1.1.2 公共语言运行库 9 1.2 ASP.NET控件 10 1.2.1 ASP.NET控件概览 11 1.2.2 HTML控件 12 1.2.3 理解...

    ASP.NET.4揭秘

    1.3.6 调试和跟踪asp.net页面33 1.3.7 跟踪页面执行36 1.4 安装asp.net38 .1.5 小结40 第2章 使用标准控件41 2.1 显示信息41 2.1.1 使用label控件41 2.1.2 使用literal控件45 2.2 接收用户输入48 2.2.1 使用textbox...

    ASP.NET4高级程序设计第4版 带目录PDF 分卷压缩包 part1

    书中还深入讲述了其他ASP.NET图书遗漏的高级主题,如自定义控件的创建、图像处理、加密等。此外,《ASP.NET 4高级程序设计(第4版)》专门提供了两章的内容来教你如何用Ajax 技术制作快速响应的页面,以及如何使用微软...

    ASP.NET4高级程序设计(第4版) 3/3

    书中还深入讲述了其他ASP.NET图书遗漏的高级主题,如自定义控件的创建、图像处理、加密等。此外,《ASP.NET 4高级程序设计(第4版)》专门提供了两章的内容来教你如何用Ajax 技术制作快速响应的页面,以及如何使用微软...

    ASP.NET3.5揭秘(卷2)part1

    因为文件比较大,打包分为ASP.NET3.5揭秘(卷2)part1和ASP.NET3.5揭秘(卷2)part2。部分人下载不能解压,是因为只下载了其中一部分,需把两部分再能正常解压 第一部分 安全  第1章 使用Login控件  1.1 Login控件...

    ASP.NET 3.5 揭秘(卷2).part2

    因为文件比较大,打包分为ASP.NET3.5揭秘(卷2)part1和ASP.NET3.5揭秘(卷2)part2。部分人下载不能解压,是因为只下载了其中一部分,需把两部分再能正常解压; 第一部分 安全  第1章 使用Login控件  1.1 Login控件...

    System.Web.Optimization.Less:System.Web.Optimization的无点适配器

    System.Web.Optimization.Less PM&gt;安装包System.Web.Optimization.Less 样本: ... 在LessTransform它也用于导入的文件( @import "virtual path" less伪指令)。暂态虚拟文件通过创建自定义VirtualPathProvider

    templar:[未维护] 对 HTML 模板的预编译支持

    // we need to use a custom virtual path provider to map virtual files. var virtualPathProvider = new TemplarVirtualPathProvider ( BundleTable . VirtualPathProvider ); BundleTable . ...

Global site tag (gtag.js) - Google Analytics