将UserControl设为嵌入式资源

时间:2013-12-26 13:58:50

标签: c# asp.net embedded-resource

我正在寻找一种方法,可以将用户控件用作我的项目中的嵌入式资源。有没有办法实现这一点或请建议另一种方式来处理用户控制的功能。

如果你有任何例子,那就更好了。

1 个答案:

答案 0 :(得分:0)

对于实施嵌入式用户控件,您必须按照以下步骤操作:

步骤1.在Visual Studio 2010或Visual Web Developer 2010中创建C#“ASP.NET空Web应用程序”。将其命名为“CSASPNETAccessResourceInAssembly”。应用程序需要创建两个项目, CSASPNETAccessResourceInAssembly , CSASPNETAssembly 。

步骤2.在项目 CSASPNETAssembly 中添加用户控件和Web表单页面,此项目是目标项目,另一个项目将访问这些资源。为了与其他页面或用户控件区别开来,我们需要添加一些文本和特殊颜色边框。

步骤3.将步骤2中包含网页和用户控件的文件夹添加到 CSASPNETAccessResourceInAssembly 项目中,我们还需要添加一些文本和边框。然后我们需要添加一个母版页来显示所有项目的资源,添加一个Web表单页面并将其命名为 Default.aspx ,并在代码隐藏文件中加载用户控件和链接。对于普通的网页和用户控件,我们可以直接添加相对路径,但是对于其他程序集的资源,我们需要添加一些特殊信息来组合一个复杂的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; 
 } 
}

步骤4.一切都很好,现在我们可以开始创建自定义虚拟文件系统。在第一步中,创建一个类来继承VirtualPathProvider类并覆盖一些必要的方法,例如FileExists,GetFile,GetCacheDependency,此类用于接收和分析可以在Web请求中获取正确资源的消息。

以下代码是一个自定义虚拟路径提供程序类,可以区分 Assembly/xxx 文件夹。

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

步骤5.然后我们可以创建一个虚拟文件类,从虚拟路径提供类获取路径并检查URL是否可用,并返回相对的assembly s文件流。 以下代码显示了如何检查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; 
        } 
    } 
} 

步骤6.最后,您只需要将CustomPathProvider类注册到Application_Start事件。当您尝试运行此应用程序时,提供程序开始工作。

以下代码用于将自定义路径提供程序类注册到Application_Start事件。

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

步骤7.构建应用程序,然后进行调试。