zoukankan      html  css  js  c++  java
  • 【译】AllInOne:加载嵌入资源中的用户控件 拓荒者

    原文地址:http://code.msdn.microsoft.com/CSASPNETAccessResourceInAss-6725d61a

    你可以在原文中下载源代码,我在文章中不再提供下载链接。

    介绍

      本项目举例说明了如何通过虚拟路径访问类库中的用户控件和页面,我们继承了VirtualPathProvider和VirtualFile类创建了一个自定义路径提供程序,这个虚拟文件系统能够提供一类像似的文件路径,供不同的程序访问文件或代码。例如,我们可以将相同类型但在不同程序集(a.dll, b.dll)中的文件(a.mp3, b.mp3)使用统一的虚拟路径,像 http://localhost/mp3/a.mp3http://localhost/mp3/b.mp3。通过这种方法,我们的网站变得更加清晰和易于交互。

    运行示例程序

    跟着示例的步骤:

    第一步:打开CSASPNETAccessResourceInAssembly.sln,展开CSASPNETAccessResourceInAssembly Web应用程序,按CTRL+ F5浏览Default.aspx。

    第二步:我们将会在页面上看到两个用户控件和两个连接,红色边框部分和它下面的连接来自CSASPNETAssembly项目,蓝色边框部分和WebSite/WebPage连接来自本项目。

    第三步:你可以点击两个连接来查看两个不同程序集中的页面,Assembly/WebPage 是CSASPNETAssembly项目的页面,Website/WebPage是当前项目的页面。

    来自CSASPNETAssembly的页面:

    来自本项目的页面:

    第四步:完成

    用到的代码

    代码逻辑:

    第一步:在Visual Studio 2010 或 Visual Web Developer 2010中创建一个空的Web应用程序,命名为“CSASPNETAccessResourceInAssembly”。这个程序需要新建两个项目:“CSASPNETAccessResourceInAssembly”和“CSASPNETAssembly”。

    第二步:在项目CSASPNETAssembly中,创建一个用户控件也Web页面,这个项目是目标项目,另外一个会访问它的资源。为了使页面和用户控件看上去和别的不同,我们需要为他们加入一些文字和特殊颜色的边框。

    第三步:像第二步一样为CSASPNETAccessResourceInAssembly添加页面和用户控件,同样需要添加一些文字和边框。然后我们需要添加一个模板页来显示这些资源,新增一个名字为default.aspx的页面,在后台代码中添加加载用户控件和连接。常规的web页面和用户控件,我们可以用相对路径直接访问,但对于程序中的资源,我们需要在url中加入一些特殊的信息。

    使用一下代码为default.aspx添加控件和链接:

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

    第四步:万事俱备,现在我们可以创建自定义虚拟文件系统了。首先,创建一个继承自VirtualPathProvider 的类,重写一些必要的方法,例如FileExists、GetFile、GetCacheDependency,这个类用来接收和解析来自web请求,以获得正确的资源。

        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);
                }
            }
        }

    第五步:然后创建一个虚拟文件类,用来从CustomPathProvider获取路径,并检查url是否合法,并返回相对于程序集的文件流。

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

    第六步:最后,你需要在Application_Start 事件中注册CustomPathProvider 类,这个提供者会随着程序一起运行。

            protected void Application_Start(object sender, EventArgs e)
            {
                HostingEnvironment.RegisterVirtualPathProvider(new CustomPathProvider());
            }

    第七步:编译并调试。

  • 相关阅读:
    纠结
    oracle大批量数据更新
    SQL Server 2008 “因为数据库正在使用,所以无法获得对数据库的独占访问权”解决方法
    面试总结
    Oracle 存储过程发送邮件
    ASP.NET页面之间传递值的几种方法<转>
    模式窗口里面,服务器控件添加确认操作时,又弹出新窗口
    深入研究Asp.net页面的生命周期<转>
    asp.net用jquery为服务器控件添加javascript处理
    sqlserver 把对象发布成webservice遇到的问题
  • 原文地址:https://www.cnblogs.com/youring2/p/2548235.html
Copyright © 2011-2022 走看看