首页 > 代码库 > [转] 通过 VirtualPathProvider 使用嵌入资源
[转] 通过 VirtualPathProvider 使用嵌入资源
VirtualPathProvider类,提供了一组方法,使 Web 应用程序可以从虚拟文件系统中检索资源。
参见MSDN:http://msdn.microsoft.com/zh-cn/library/system.web.hosting.virtualpathprovider.aspx
遇到这样一个需求,要将.ascx作为嵌入资源放到一个Library项目中,在Web App中需要可以使用。
上网查找后发现,VirtualPathProvider类可以实现这个目的。
步骤一:
通过继承VirtualPathProvider类,实现自己的AssemblyResourceVirtualPathProvider,用来为Assembly中的Resource提供支持。
1 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> 2 public class AssemblyResourceVirtualPathProvider : System.Web.Hosting.VirtualPathProvider 3 { 4 /// <summary> 5 /// AssemblyPath与VirtualPath映射 6 /// </summary> 7 private string _VirtualPath; 8 private string _AssemblyPath; 9 10 private string VirtualPath { get { return _VirtualPath; } } 11 private string AssemblyPath { get { return _AssemblyPath; } } 12 13 public AssemblyResourceVirtualPathProvider(string virtualPath, string assemblyPath) 14 { 15 _VirtualPath = "~/" + virtualPath; 16 _AssemblyPath = assemblyPath; 17 } 18 19 /// <summary> 20 /// 是否是AssemblyResource类型的VirtualPath 21 /// </summary> 22 /// <param name="virtualPath">virtualPath</param> 23 /// <returns></returns> 24 private bool IsAssemblyResourceVirtualPath(string virtualPath) 25 { 26 string path = VirtualPathUtility.ToAppRelative(virtualPath); 27 return path.StartsWith(VirtualPath, StringComparison.InvariantCultureIgnoreCase); 28 } 29 30 /// <summary> 31 /// 获取virtualPath对应Assembly内的ResourceName 32 /// </summary> 33 /// <param name="virtualPath">virtualPath</param> 34 /// <returns></returns> 35 private string GetResourceName(string virtualPath) 36 { 37 return VirtualPathUtility.GetFileName(virtualPath); 38 } 39 40 #region override 41 42 /// <summary> 43 /// 获取VirtualFile 44 /// </summary> 45 /// <param name="virtualPath"></param> 46 /// <returns></returns> 47 public override VirtualFile GetFile(string virtualPath) 48 { 49 if (IsAssemblyResourceVirtualPath(virtualPath)) 50 { 51 string resourceName = this.GetResourceName(virtualPath); 52 return new AssemblyResourceVirtualFile(virtualPath, AssemblyPath, resourceName); 53 } 54 else 55 { 56 return Previous.GetFile(virtualPath); 57 } 58 } 59 60 /// <summary> 61 /// virtualPath指定的文件是否存在。 62 /// </summary> 63 /// <param name="virtualPath"></param> 64 /// <returns></returns> 65 public override bool FileExists(string virtualPath) 66 { 67 if (IsAssemblyResourceVirtualPath(virtualPath)) 68 { 69 //return true; 70 Assembly assembly = Assembly.LoadFrom(AssemblyPath); 71 if (assembly != null) 72 { 73 string resourceName = this.GetResourceName(virtualPath); 74 return (assembly.GetManifestResourceInfo(resourceName) != null); 75 } 76 return false; 77 } 78 else 79 { 80 return Previous.FileExists(virtualPath); 81 } 82 } 83 84 public override bool DirectoryExists(string virtualDir) 85 { 86 if (IsAssemblyResourceVirtualPath(virtualDir)) 87 { 88 return true; 89 } 90 else 91 { 92 return Previous.DirectoryExists(virtualDir); 93 } 94 } 95 96 public override string GetFileHash(string virtualPath, IEnumerable virtualPathDependencies) 97 { 98 return null; 99 100 //HashCodeCombiner combiner = new HashCodeCombiner();101 //foreach (string str in virtualPathDependencies)102 //{103 // string fileName = HostingEnvironment.MapPathInternal(str);104 // combiner.AddFile(fileName);105 //}106 //return combiner.CombinedHashString;107 }108 109 public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart)110 {111 return null;112 113 //System.Collections.Specialized.StringCollection fullPathDependencies = null;114 115 //// Get the full path to all dependencies.116 //foreach (string virtualDependency in virtualPathDependencies)117 //{118 // if (fullPathDependencies == null)119 // fullPathDependencies = new System.Collections.Specialized.StringCollection();120 121 // fullPathDependencies.Add(virtualDependency);122 //}123 //if (fullPathDependencies == null)124 // return null;125 126 //// Copy the list of full-path dependencies into an array.127 //string[] fullPathDependenciesArray = new string[fullPathDependencies.Count];128 //fullPathDependencies.CopyTo(fullPathDependenciesArray, 0);129 //// Copy the virtual path into an array.130 //string[] virtualPathArray = new string[1];131 //virtualPathArray[0] = virtualPath;132 133 //return new CacheDependency(virtualPathArray, fullPathDependenciesArray, utcStart);134 }135 136 //public override string CombineVirtualPaths(string basePath, string relativePath)137 //{138 // if (IsAssemblyResourceVirtualPath(basePath))139 // {140 // return null;141 // }142 // else143 // {144 // return Previous.CombineVirtualPaths(basePath, relativePath);145 // }146 //}147 148 //public override System.Runtime.Remoting.ObjRef CreateObjRef(Type requestedType)149 //{150 // return Previous.CreateObjRef(requestedType);151 //}152 153 //public override string GetCacheKey(string virtualPath)154 //{155 // if (IsAssemblyResourceVirtualPath(virtualPath))156 // {157 // return null;158 // }159 // else160 // {161 // return Previous.GetCacheKey(virtualPath);162 // }163 //}164 #endregion165 }
步骤二:
通过继承VirtualFile类,实现AssemblyResourceVirtualPathProvider的AssemblyResourceVirtualFile,用来提供Resource的Open。
1 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> public class AssemblyResourceVirtualFile : VirtualFile 2 { 3 private string AssemblyPath; 4 private string ResourceName; 5 6 public AssemblyResourceVirtualFile(string virtualPath, string assemblyPath, string resourceName) 7 : base(virtualPath) 8 { 9 AssemblyPath = assemblyPath;// Path.Combine(HttpRuntime.BinDirectory, assemblyPath);10 ResourceName = resourceName;11 }12 13 public override System.IO.Stream Open()14 {15 Assembly assembly = Assembly.LoadFrom(AssemblyPath);16 if (assembly != null)17 {18 return assembly.GetManifestResourceStream(ResourceName);19 }20 return null;21 }22 }
步骤三:
在Global.asax中注册VirtualPathProvider。
1 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> 2 protected void Application_Start(object sender, EventArgs e) 3 { 4 string assemblyPath = "WebControlLibrary.dll"; 5 assemblyPath = Path.Combine(HttpRuntime.BinDirectory, assemblyPath); 6 AssemblyResourceVirtualPathProvider provider = new AssemblyResourceVirtualPathProvider("WebControlDemo", assemblyPath); 7 8 //按链表方式链接注册的VirtualPathProvider。 9 HostingEnvironment.RegisterVirtualPathProvider(provider);10 }
步骤四:
创建Library项目,添加Web User Control,将.ascx文件为嵌入资源。
步骤五:
在Web App的页面中使用Web User Control。
1 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> protected override void OnInit(EventArgs e) 2 { 3 //LoadControl中获取对程序集内资源 4 //当然,可以在aspx中使用: 5 //<%@ Register Src="http://www.mamicode.com/WebControlDemo/WebControlLibrary.WebUserControl.ascx" TagName="WebUserControl" TagPrefix="uc1" %> 6 //<uc1:WebUserControl id="WebUserControl1_1" runat="server"/> 7 WebUserControl1 = this.LoadControl("WebControlDemo/WebControlLibrary.WebUserControl.ascx") as WebUserControl; 8 SubWebUserControl1 = this.LoadControl("WebControlDemo/WebControlLibrary.SubDirectory.SubWebUserControl.ascx") as SubWebUserControl; 9 this.form1.Controls.Add(WebUserControl1);10 this.form1.Controls.Add(SubWebUserControl1);11 base.OnInit(e);12 }
结束语:
通过嵌入资源的联想,可以将JS文件作为嵌入资源,同样可以通过VirtualPathProvider提供访问支持。
1 //获取对程序集内资源的 URL 引用 的 虚拟路径方法 2 //当然,可以在aspx中使用:<script language="javascript" src="http://www.mamicode.com/WebControlDemo/WebControlLibrary.VirtualPathProvider.js"></script> 3 if (!this.ClientScript.IsClientScriptIncludeRegistered(GetType(), "JS By VirtualPathProvider")) 4 { 5 string webUrl = "WebControlDemo/WebControlLibrary.VirtualPathProvider.js"; 6 this.ClientScript.RegisterClientScriptInclude(GetType(), "JS By VirtualPathProvider", webUrl); 7 } 8 9 //获取对程序集内资源的 URL 引用 的 一般方法10 if (!this.ClientScript.IsClientScriptIncludeRegistered(GetType(), "JS By WebResourceUrl"))11 {12 string webUrl = Page.ClientScript.GetWebResourceUrl(new WebUserControl().GetType(), "WebControlLibrary.WebResourceUrl.js");13 this.ClientScript.RegisterClientScriptInclude(GetType(), "JS By WebResourceUrl", webUrl);14 }
代码示例:http://files.cnblogs.com/xujiaoxiang/WebDemo.zip
[转] 通过 VirtualPathProvider 使用嵌入资源