正题
先看下我的最终的目录结构(这是工程结构就是 英文原站下载的代码):
这里需要说明几点:
1. 对于以下这行资源注册代码放在AssemblyInfo.cs中和放在DLL中任何类的namespace前效果是一样的。(我个人建议统一放在AssemblyInfo.cs中便于统一管理)
[assembly: WebResource( " FunkyTextBox.Resources.test.jpg " , " image/jpeg " )] 2. 资源文件在DLL中的位置和访问是有关系的!!我把图上test.jpg放在根目录和放在Resources目录下访问起来是不一样的,注册资源的时候就是根据这个来(也就是说如果放在根目录的话注册资源的名称就是"FunkyTextBox.test.jpg")。
现在我们先分析FunkyTextBox他原来的代码架构,也是很多网上示例的架构:
1. 把资源文件拷贝到项目中
2. 编写自己的用户控件,继承WebControl如TextBox,也就是说在DLL内部调用资源文件
3. 在用户控件中注册资源(也可以在AssemblyInfo.cs中)
基本上看到的都是在DLL内部调用资源文件然后再从外部引用该自定义控件。这里我主要讨论的是想在外部直接引用DLL内部的资源文件,相信很多朋友和我一样,把DLL内部引用资源文件的代码复制出来拷贝到ASPX里面图片怎么都出不来,包括注册httphandles里面截获WebResource.axd也不管用。直到在MSDN上看到那段代码才有所感悟:
using System; using System.Web; using System.Web.UI; using System.Security.Permissions; [assembly: WebResource( " Samples.AspNet.CS.Controls.script_include.js " , " application/x-javascript " )] namespace Samples.AspNet.CS.Controls { [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)] public class ClientScriptResourceLabel { // Class code goes here. } }
<% @ Page Language = " C# " %> <% @ Import Namespace = " Samples.AspNet.CS.Controls " %> <! DOCTYPE html PUBLIC " -//W3C//DTD XHTML 1.0 Transitional//EN " " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd " > < script runat = " server " > public void Page_Load(Object sender, EventArgs e) { // Define the resource name and type. String rsname = " Samples.AspNet.CS.Controls.script_include.js " ; Type rstype = typeof (ClientScriptResourceLabel); // Get a ClientScriptManager reference from the Page class. ClientScriptManager cs = Page.ClientScript; // Write out the web resource url. ResourcePath.InnerHtml = cs.GetWebResourceUrl(rstype, rsname); // Register the client resource with the page. cs.RegisterClientScriptResource(rstype, rsname); } </ script > < html > < head > < title > ClientScriptManager Example </ title > </ head > < body > < form id = " Form1 " runat = " server " > The web resource path is < span id = " ResourcePath " runat = " server " /> . < br />< br /> < input type = " text " id = " Message " /> < input type = " button " onclick = " DoClick() " value = " ClientClick " /> </ form > </ body > </ html > 为了方便直接看到效果,我把上面从DLL中读取JS的代码改成了从DLL中读取图片的代码,改动如下
1. 将ClientScriptResourceLabel命名空间改为FunkyTextBox
2. 将资源注册代码改成如下(注意资源路径):
[assembly: WebResource( " FunkyTextBox.Resources.test.jpg " , " image/jpeg " )] 3. 为ASPX页面添加一个图片按钮并把读取的相应改成如下:
< script runat = " server " > public void Page_Load(Object sender, EventArgs e) { // Define the resource name and type. String rsname = " FunkyTextBox.Resources.test.jpg " ; Type rstype = typeof (ClientScriptResourceLabel); // Get a ClientScriptManager reference from the Page class. ClientScriptManager cs = Page.ClientScript; // Write out the web resource url. imgpath.Src = cs.GetWebResourceUrl(rstype, rsname); // ResourcePath.InnerHtml = // Register the client resource with the page. // cs.RegisterClientScriptResource(rstype, rsname); } </ script > < html xmlns = " http://www.w3.org/1999/xhtml " > < head runat = " server " > < title > WebResources </ title > </ head > < body > < form id = " form1 " runat = " server " > < div > < img runat = " server " id = " imgpath " alt = "" /> 上面访问代码可以简化如下: mgpath.Src = ClientScript.GetWebResourceUrl( typeof (FunkyTextBox), " FunkyTextBox.Resources.test.jpg " ); 由上面的代码我们可以看得出,ClientScriptResourceLabel类里面是空的,唯一有用的就是注册了一下资源,接下来我们把ClientScriptResourceLabel里面的资源注释掉,把资源注册到AssemblyInfo.cs中,也能够正确显示。这就让我纳闷了!type指向的是一个空的类也能够显示资源,但是我用this.GetType()或用typeof(_Default)通通都不行!!我猜想这个GetWebResourceUrl第一个参数只需要我们把他指引向正确的DLL空间就行了,然后就可以找到资源了!?还有我用Assembly.Load("FunkyTextBox").GetType()来指定Type也是不行的,感觉还是学得比较浅:)
现在基本能达到我的直接访问内部资源文件的要求了,只是需要多一个空类来指定type,暂时满足我的要求,目前可以考虑把JS放到这个里面来,这样一来如果拷贝生成JS的SRC链接直接访问可是不行的哦!就到这里,欢迎多多交流!
本文转自over140 51CTO博客,原文链接:http://blog.51cto.com/over140/586490,如需转载请自行联系原作者