首页 > 代码库 > [转] 通过 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     }
View Code

 

步骤二:

通过继承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     }
View Code

 

步骤三:

在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         }
View Code

 

步骤四:

创建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         }
View Code

 

结束语:

通过嵌入资源的联想,可以将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             }
JS嵌入

 

 代码示例:http://files.cnblogs.com/xujiaoxiang/WebDemo.zip

[转] 通过 VirtualPathProvider 使用嵌入资源