ASP.NET 2.0 中的 Web Resource
文/黃忠成
緣起
有讀者購買了ASP.NET【極意之道-ASP.NET AJAX/Silverlight聖典】,對於書中使用Web Resource的模式來嵌入script至Assembly的方式相當有興趣,來信詢問到如何將圖形或是其它檔案嵌入Assembly的方法,這其實不難,只要詢書中的模式一步一步做即可,只是書中是將script嵌入控件所在的Assembly中,而不是ASP.NET專案中,因此我特別撰寫此篇文章,介紹如何將圖形檔嵌入ASP.NET專案中。
Why?
將script嵌入控件所在的Assembly目的是為了減少分發時的檔案數量,同時獲得script內容不被修改的優點,那把圖形等其它資源嵌入ASP.NET專案中是為了什麼呢?答案其實是一樣的,這種做法可減少分發時的檔案數量,同時嵌入的圖形由於位於Assembly中,也可以獲得不被修改的優點。不過後者有個前提,那就是你必須在Code-Behind的程式中來指定資源的URL位置,而不是在.aspx中指定,因為一旦在.aspx中指定,那麼使用者便可透過修改.aspx來改變URL,當然!使用者不該如此做,但!誰知道呢?無論如何,將圖形等資源檔內嵌於ASP.NET專案所產生的Assembly中,至少可以減少分發時的檔案數量。
於ASP.NET專案中內嵌圖形
這其實很簡單,只要建立Web Application專案(此法不適用於Web Site模式),然後將所需的圖形檔(本例是IMG_1693.JPG)加到專案中,於Solution Explorer上點選該項目,然後切到屬性視窗,修改為Embedded Resource即可。
圖001
接著請開啟AssemblyInfo.cs,鍵入下列程式碼之粗體字部份。
using System.Reflection; using System.Web.UI; using System.Runtime.CompilerServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("WebApplication2")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("GIS")] [assembly: AssemblyProduct("WebApplication2")] [assembly: AssemblyCopyright("Copyright © GIS 2008")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("3d5900ae-111a-45be-96b3-d9e4606ca793")]
// Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: WebResource("WebApplication2.IMG_1693.JPG", "image/jpeg")] |
請特別注意,WebResource的第一個參數是Resource名稱,此名稱是以<命名空間.檔案名稱>格式存在,本例的專案名稱為WebApplication2,預設的命名空間是WebApplication2,而圖形檔案名稱為IMG_1693.JPG,所以結合後應是【WebApplication2.IMG_1693.JPG】,第二個參數是檔案的格式,此圖形檔是JPEG格式,所以使用【image/jpeg】。完成這些步驟後,請切換到.aspx,鍵入下列粗體字的程式碼。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication2._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> <img src="<%= ClientScript.GetWebResourceUrl(typeof(WebApplication2._Default),"WebApplication2.IMG_1693.JPG") %>" /> </div> </form> </body> </html>
|
當我們要取得Web Resource所對應的URL時,必須呼叫ClientScript(Page的屬性)的GetWebResourceUrl函式,於第一個參數傳入該資源所在Assembly的型別,第二個參數則傳入資源名稱,也就是於AssemblyInfo.cs中 定義WebResource時的第一個參數。請特別注意一點,當使用GetWebResourceUrl時,我傳入的第一個參數是【typeof(WebApplication2._Default)】,許多人會在此處直接以GetType()取代,這是行不通的,因為ASP.NET在執行網頁時,會以Assembly+.aspx後產生出一個暫時的Ghost Page Class(請參照深入剖析ASP.NET 元件設計一書),此Ghost Page Class是繼承自_Default,然後放在另一個Assembly中,也就是說,GetType()取到的型別是位於另一個Assembly中,而非ASP.NET專案所產生的那一個,裡面沒有我們所定義的內嵌資源,結果便是出現404的錯誤。
以程式來指定URL
除了可在.aspx以inline-script來取得WebResource的URL並指定給特定控件外,我們也可以透過程式來指定,如下所示。
.aspx |
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication2._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> <img src="<%= ClientScript.GetWebResourceUrl(typeof(WebApplication2._Default),"WebApplication2.IMG_1693.JPG") %>" /> <asp:Image ID="IMG1" runat=server /> </div> </form> </body> </html> |
.aspx.cs |
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls;
namespace WebApplication2 { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { IMG1.ImageUrl = ClientScript.GetWebResourceUrl(typeof(_Default), "WebApplication2.IMG_1693.JPG"); } } } |