[转] 通过 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         //    else
143         //    {
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         //    else
160         //    {
161         //        return Previous.GetCacheKey(virtualPath);
162         //    }
163         //}
164         #endregion
165     }

步骤二:

通过继承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="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="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

时间: 2024-08-25 19:52:32

[转] 通过 VirtualPathProvider 使用嵌入资源的相关文章

c# 嵌入资源文件

欢迎转载,转载请注明:转载自[ http://www.cnblogs.com/zjfree/ ] 开发环境:VS2005 C# 首先将要嵌入的资源拷贝到工程目录下. 设置文件生成操作为:嵌入的资源 获取嵌入资源代码如下: 1 2 3 4 5 6 7 8 9 10 private void Form1_Load(object sender, EventArgs e) {     Stream sm = Assembly.GetExecutingAssembly().GetManifestResou

WP8.1开发中关于媒体(图片)文件的生成操作,属性如何设置(内容/嵌入资源等);

(转载)WindowsPhone问题笔记-- 正确选择build action 解决媒体资源无法读取问题 链接:http://www.cnblogs.com/qinxg/archive/2012/07/17/2594503.html 在开发过程中遇到了图片加载器与视频播放器无法正常读取媒体资源的问题. 在代码中 图片路径是正确的,图片无法正常读出.而视频部分采取相同的代码,却可以正常读出. 读取图片代码如下: 读取视频代码如下: (转载)WindowsPhone问题笔记-- 正确选择build

嵌入资源第三讲:多格式文件内嵌入WPF资源文件

作为一个扩展,你需要了解DotNetZip用法,请参见:C# .NET 使用第三方类库DotNetZip解压/压缩Zip文件 你也需要了解单文件内嵌入资源文件基本方法,参见:WPF调用嵌入的非.net的EXE资源文件 作者:一剑 如果你有一大堆文件或者想通过打包的方式嵌入任意格式的文件到资源文件中,那么你可以打包成一个ZIP文件,再嵌入到资源文件中是一个不错的选择: using System.Reflection;//++ using System.IO; using Ionic.Zip; na

Asp.net 自定义控件开发相关的几种嵌入资源解决方案

前提: 如下将要介绍的几种类型资源都要在其属性页窗口, 将 <生成操作> 属性, 设置为[嵌入的资源], 如图: ? 给自定义控件添加自定义图标的几种方案 方法一: 直接在自定义控件项目中添加一个 *.bmp格式的图标文件, 并将其命名 与主控件文件相同, 扩展名为 .bmp, 比如主控件文件名为: CustomButton.cs, 则图标文件命名为: CustomButton.bmp . 编译项目. 然后在工具箱中添加此控件就可以看到刚刚设置的图标效果. 方法二: 图标文件名称与主控件名称不

asp.net 自定义控件 嵌入资源文件 备忘

要想在自定义用户控件中嵌入资源,从以下几个步骤入手: 1.在AssemblyInfo.cs中注册资源,文件夹层级用点隔开.例如: [assembly: System.Web.UI.WebResource("FirsteLite.OMS.Checking.UserControls.test.jpg", "image/jpg")] 2.修改资源文件的"生成操作"的值为“嵌入的资源". 3.在代码里引用的时候可以用Page.ClientScr

abp 嵌入资源(视图、css、js)的访问

最近在做的基于abp作为框架的一个项目,将一些属于框架功能的页面写在了一个独立程序集中,然后在web项目中引用该程序集达到访问框架页面目的. 这样一来发布web之后,在发布目录中是看不到写在另一个程序集中的页面,这样有利于框架功能与业务功能的分离.在框架做了修改以后,只需要在业务项目中替换引用的框架dll文件即可,维护起来比较方便. 这种想法还是比较好的,但在实施时遇到一个情况:web发布以后,如果直接挂在IIS的网站上能够访问内嵌视图(完全正常),但如果挂载在网站下的应用程序下(虚拟网站)就不

abp 将abp项目发布之后挂在IIS上无法访问嵌入资源的问题

在本地调试是能够正常访问到写在另一个程序集中的嵌入资源,但是发布之后 挂在IIS上却不能访问. 整了半天没找到原因.后来发现是发布时配置错误造成的:取消勾选precompile during publishing选项.看截图:

C# 类库使用嵌入资源

1.将资源文件的属性改成“嵌入资源” 2. 1 string assembleName = this.GetType().Assembly.GetName().Name;//本程序集名 2 Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(string.Format("{0}.{1}", assembleName, xmlPath));//获取嵌入资源生成流,XMLPATH为嵌入资源路径,

Mvc5中使用Js嵌入资源访问

有些项目在一些特殊场景下会把Js文件作为嵌入资源打包进dll中 网上各种搜索都没有解决方案. 后来琢磨的时候发现... ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 1. 设置js文件为嵌入资源 2. 读取内嵌的资源文件(js文件)为FileStreamResult public FileStreamResult Index(){ //获取程序集 Assembly asy = Assembly.Load("程序集名称"); //也就是命名空间 //获取文件流 var st