前言
出於安全以及移植考慮,近兩天有看關於WebResource方面的資料,有點點心得和不明白。這裡鄙視下那些狂抄襲的論壇和部落格,一搜尋幾乎全一樣,也沒多說一個字的!!
感謝
1.MSDN 直到這個例子出現,我才真正做出自己想要的東西,但是也帶來了一些不明白
2.利用WebResource.axd通過一個URL來訪問裝配件的內建資源(譯) 這篇文章給了我基礎代碼
3.在自訂Server Control中捆綁JS檔案 這是一篇好文章,雖然沒有用到,但是值得推薦
正題
先看下我的最終的目錄結構(這是工程結構就是利用WebResource.axd通過一個URL來訪問裝配件的內建資源(譯) 英文原站下載的代碼):
這裡需要說明幾點:
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連結直接存取可是不行的哦!就到這裡,歡迎多多交流!
補充——代碼下載[2008-9-24]:
當時寫的Demo,是在別人的源碼基礎上改的:http://files.cnblogs.com/over140/FunkyTextBox.rar