我正在寻找一种方法,可以将用户控件用作我的项目中的嵌入式资源。有没有办法实现这一点或请建议另一种方式来处理用户控制的功能。
如果你有任何例子,那就更好了。
答案 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.构建应用程序,然后进行调试。