19.2 移動Web網站
利用ASP.NET創建移動Web網站時,可以包含ASP.NET能夠識別處理的特定類型的文件。此外,還可以創建用於特殊用途(如用於存儲源代碼)的文件夾。本節介紹有關ASP.NET能夠識別以進行特殊處理的文件和文件夾,以及如何在應用程序中引用它們的內容。
19.2.1 移動Web網站佈局
可以將網站的文件保存在方便應用程序訪問的任何文件夾結構中。除此ASP.NET還保留了一些可用於特定類型的文件和文件夾定義。
1. 默認頁面
可以爲應用程序建立默認頁面,這將使用戶更容易定位到移動Web站點。默認頁面是用戶訪問移動Web站點時,沒有指定特定頁面的情況下站點爲用戶默認提供的頁面。例如,可以創建一個名爲Default.aspx的頁面,並將它保存在移動Web站點的根文件夾中。如果用戶在訪問移動Web站點時沒有指定特定頁面,如直接使用http://www.contoso.com的Url訪問,則可以配置移動Web站點,以便自動請求Default.aspx頁面。默認頁可以作爲移動Web站點的主頁,或者在頁面中寫入代碼重定向到其他Url。
2. 應用程序文件夾
ASP.NET能夠識別用於特定類型內容的文件夾名稱。表19-1列出了保留的文件夾名稱以及文件夾中通常包含的文件類型。
表19-1 ASP.NET的應用程序文件夾
文件夾 |
說明 |
App_Browsers |
包含ASP.NET用於標識個別瀏覽器並確定其功能的瀏覽器定義(.browser)文件 |
App_Code |
包含希望作爲應用程序一部分進行編譯的類和業務對象(例如.cs和.vb文件)的源代碼。在動態編譯的應用程序中,當對應用程序發出首次請求時,ASP.NET編譯App_Code文件夾中的代碼,然後在檢測到任何更改時重新編譯該文件夾中的項 |
App_Data |
包含應用程序數據文件,包括MDF文件、XML文件和其他數據存儲文件ASP.NET 2.0使用App_Data文件夾來存儲應用程序的本地數據庫,該數據庫可用於維護成員資格和角色信息 |
App_WebReferences |
包含用於定義在應用程序中使用的Web引用的引用協定文件(.wsdl文件)、架構(.xsd文件)和發現文檔文件(.disco和.discomap文件) |
App_GlobalResources |
包含編譯到具有全局範圍的程序集中的資源(.resx和.resources文件)App_GlobalResources文件夾中的資源是強類型的,可以通過編程方式進行訪問 |
App_LocalResources |
包含與應用程序中的特定頁面、用戶控件或母版頁關聯的資源(.resx和.resources文件) |
App_Themes |
包含用於定義ASP.NET網頁和控件外觀的文件集合(.skin和.css文件以及圖像文件和一般資源) |
Bin |
包含要在應用程序中引用的控件、組件或其他代碼的已編譯程序集(.dll文件)。在應用程序中將自動引用Bin文件夾中的代碼所表示的任何類 |
3. 管理子文件夾
站點的配置設置可以通過Web.config文件進行管理,該文件位於站點的根文件夾中。如果在子文件夾中包含有文件,則可以通過在該文件夾中創建Web.config文件來爲這些文件維護單獨的配置設置。如果配置設置作爲整體應用於站點,則不能在子文件夾級別設置或重寫這些設置。
4. 訪問權限
如果需要限制對移動Web站點內容的訪問,則可以通過配置來限制對個別文件或子文件夾的訪問權限的設置。通常可以按用戶或角色(組)限制內容。
19.2.2 移動Web網站文件類型
移動Web站點應用程序中可以包含多種文件類型,其中一些文件類型由ASP.NET支持和管理,而其他文件類型則由IIS服務器支持和管理。大多數ASP.NET文件類型,都可以使用Visual Studio 2005中的“添加新項”菜單項創建。
使用應用程序映射,可以將文件類型映射到應用程序。例如,當打開一個具有.txt文件擴展名的文件時,很可能會打開記事本應用程序,因爲默認情況下.txt文件類型已映射到Notepad.exe。在Web應用程序中,文件類型會映射到IIS中的應用程序擴展。
通過程序映射由ASP.NET管理的主要文件類型如表19-2所示。
表19-2 由ASP.NET管理的主要文件類型
文件類型 |
位置 |
說明 |
.asax |
應用程序根目錄 |
通常是Global.asax文件 |
.ascx |
應用程序根目錄或子目錄 |
Web用戶控件文件 |
.asmx |
應用程序根目錄或子目錄 |
XML Web services文件 |
.aspx |
應用程序根目錄或子目錄 |
ASP.NET的Web窗體文件 |
.config |
應用程序根目錄或子目錄 |
通常是 Web.config 配置文件 |
.cs、.vb |
App_Code子目錄;但如果是ASP.NET頁的代碼隱藏文件,則與網頁位於同一目錄 |
運行時要編譯的類源代碼文件 |
.dll |
Bin子目錄 |
已編譯的類庫文件 |
.mdb、.ldb、.mdf |
App_Data子目錄 |
數據庫文件 |
.resources、.resx |
App_GlobalResources 或 App_LocalResources 子目錄 |
資源文件 |
通過程序映射由IIS管理的主要文件類型如表19-3所示。
表19-3 由IIS管理的主要文件類型
文件類型 |
位置 |
說明 |
.asa |
應用程序根目錄 |
通常是Global.asa文件 |
.asp |
應用程序根目錄或子目錄 |
ASP頁面文件 |
.config |
應用程序根目錄或子目錄 |
通常是 Web.config 配置文件 |
.cs、.vb |
App_Code子目錄;但如果是ASP.NET頁的代碼隱藏文件,則與網頁位於同一目錄 |
運行時要編譯的類源代碼文件 |
(續表)
文件類型 |
位置 |
說明 |
.dll |
Bin子目錄 |
已編譯的類庫文件 |
.mdb、.ldb、.mdf |
App_Data子目錄 |
數據庫文件 |
.resources、.resx |
App_GlobalResources或App_LocalResources子目錄 |
資源文件 |
.css |
應用程序根目錄或子目錄,或App_Themes子目錄 |
用於確定HTML元素格式的樣式表文件 |
.htm、.html |
應用程序根目錄或子目錄 |
用HTML代碼編寫的靜態Web文件 |
19.2.3 移動Web網站路徑
使用移動Web站點中的資源時,通常必須指定資源的路徑。例如,可以使用URL路徑引用頁面中的圖像文件或網站中其他位置處頁面的URL。同樣,移動Web應用程序中的代碼,可以使用基於服務器文件的物理文件路徑對文件進行讀寫操作。ASP.NET提供用於引用資源,並確定應用程序中的頁面或其他資源的路徑的方法。通常頁面中的元素或移動控件必須引用外部資源,如文件。ASP.NET可以通過各種方法引用外部資源,而所選的具體方法取決於使用客戶端元素還是移動控件。
客戶端元素以原樣傳遞給瀏覽器。因此,從客戶端元素中引用資源時,應根據HTML中URL的標準規則構造路徑。可以使用絕對URL路徑,也可以使用各種類型的相對路徑。例如,如果頁面包含一個img標記,則可使用如下所示的絕對URL路徑或站點根目錄相對路徑來設置其src屬性。
<img src="http://www.contoso.com/MyApplication/Images/Pic.jpg" />
<img src="../Images/Pic.jpg" />
移動控件在引用資源時,同樣可以使用絕對路徑或相對路徑。如果使用相對路徑,可以使用Web應用程序根目錄運算符(~),在移動控件中指定路徑時,可以使用該運算符。ASP.NET會將根目錄運算符解析爲當前應用程序的根目錄,可以結合使用根目錄運算符和文件夾來指定基於當前根目錄的路徑。例如,假設一個用戶控件包含一個Image移動控件,圖像文件存放在根目錄的Images文件夾下,則該移動控件的ImageUrl屬性設置爲以下路徑:
<mobile:Image ID="Image1" Runat="server" ImageUrl="="~/Images/Pic.jpg">
</mobile:Image>
在該示例中,圖像文件將從Web應用程序根目錄的Images文件夾中直接讀取,無論該頁面位於站點的什麼位置。開發移動Web網站,可以在移動控件的任何與路徑有關的屬性中使用根目錄運算符。
19.2.4 移動Web網站中的共享代碼文件夾
如果移動Web應用程序包括要在多個頁之間共享的代碼,則可以將代碼保存在Web應用程序根目錄下的兩個特殊文件夾Bin文件夾或App_Code文件夾中。
Bin文件夾用於存儲編譯過的程序集。Web應用程序的任何代碼都能自動引用該文件夾。例如,將某個自定義類編譯後得到的程序集,複製到Web應用程序的Bin文件夾中,這樣所有頁都可以使用這個類。Bin文件夾中的程序集無需註冊。只要.dll文件存在於Bin文件夾中,ASP.NET就可以識別它。如果更改了.dll文件,並將它的新版本重新複製到Bin文件夾中,ASP.NET會檢測到更新,並對隨後的新頁請求使用新版本的.dll文件,也就是業界常說的Web應用熱部署。
App_Code文件夾用於存儲源代碼,在運行時ASP.NET將自動對這些代碼進行編譯。Web應用程序中的其他任何代碼都可以訪問產生的程序集。因此,App_Code文件夾的工作方式與Bin文件夾很類似,而不同之處是其中存儲的是未編譯的源代碼。App_Code文件夾及其在ASP.NET Web應用程序中的特殊定義,使開發人員可以創建自定義類和其他僅源代碼文件,並在Web應用程序中使用它們,而不必單獨對它們進行編譯。App_Code文件夾通常包含以傳統類文件(即帶有.vb、.cs等擴展名的文件)的形式編寫的源代碼文件。根據需要,App_Code文件夾可以包含任意數量的文件和子文件夾。
19.2.5 移動Web應用程序生命週期
在ASP.NET中,若要對ASP.NET應用程序進行初始化並使它處理請求,必須執行一些處理步驟。ASP.NET應用程序生命週期包括以下幾個階段:
(1)用戶從Web服務器請求應用程序資源。
(2)ASP.NET接收客戶端對應用程序的第一個請求。
(3)ASP.NET爲每個請求創建並初始化核心對象。如HttpContext、HttpRequest和HttpResponse。
(4)將HttpApplication對象分配給請求。
(5)由HttpApplication管線處理請求,觸發HttpApplication類的一系列事件。
在應用程序的生命週期期間,應用程序會引發可處理的事件並調用可重寫的特定方法。若要處理應用程序事件或方法,可以在應用程序根目錄中創建一個名爲Global.asax的文件。 如果創建了Global.asax文件,ASP.NET會將其編譯爲從HttpApplication類派生的類,然後使用該派生類表示應用程序。
HttpApplication進程的一個實例,每次只處理一個請求。由於在訪問應用程序類中的非靜態成員時不需要將其鎖定,可以簡化應用程序的事件處理過程。這樣還可以將特定於請求的數據,存儲在應用程序類的非靜態成員中。例如,可以在Global.asax文件中定義一個屬性,然後爲該屬性賦一個特定於請求的值。
通過使用命名約定Application_event(如Application_BeginRequest),ASP.NET可以在Global.asax文件中將應用程序事件自動綁定到處理程序。這與將ASP.NET頁面方法自動綁定到事件(如頁的Page_Load事件)的方法類似。Application_Start和Application_End方法是不表示HttpApplication事件的特殊方法。在應用程序域的生命週期期間,ASP.NET僅調用這些方法一次,而不是對每個HttpApplication實例都調用一次。圖19-1說明了應用程序域與HttpApplication實例之間的關係。
圖19-1 應用程序域與HttpApplication實例之間的關係
表19-4列出在應用程序生命週期期間最常用的一些事件和方法。
表19-4 事件和方法
事件或方法 |
說明 |
Application_Start |
請求ASP.NET應用程序中第一個資源(如頁)時調用。在應用程序的生命週期期間僅調用一次Application_Start方法 |
Application_ event |
在應用程序生命週期中的適當時候,觸發HttpApplication類的一系列事件 |
HttpApplication.Init |
在創建了所有模塊之後,對HttpApplication類的每個實例都調用一次 |
Dispose |
在銷燬應用程序實例之前調用。可使用此方法手動釋放任何非託管資源 |
Application_End |
在卸載應用程序之前,對每個應用程序生命週期調用一次 |
19.2.6 移動Web頁面生命週期
ASP.NET頁面運行時,此頁面將經歷一個生命週期。頁面在生命週期中將執行一系列處理步驟。這些步驟包括初始化、實例化控件、還原和維護狀態、運行事件處理程序代碼以及進行呈現。瞭解頁面的生命週期非常重要,這樣就能在合適的生命週期階段編寫代碼,以達到預期效果。此外,如果開發自定義控件,則必須熟悉頁生命週期,從而正確地初始化控件,使用視圖狀態數據填充控件屬性以及運行所有控件行爲邏輯。常規頁面生命週期包括以下幾個階段:
(1)頁面請求階段。頁面請求發生在頁生命週期開始之前。
(2)開始階段。在開始階段,將設置頁屬性,如Request和Response。
(3)頁初始化階段。初始化頁面中的控件。
(4)加載階段。加載期間,如果當前請求是回發請求,則將使用從視圖狀態和控件狀態恢復的信息加載控件屬性。
(5)驗證階段。在驗證期間,將調用所有驗證程序控件的Validate方法。
(6)回發事件處理階段。如果請求是回發請求,則將調用所有事件處理程序。
(7)呈現階段。在呈現期間,將所呈現的輸出提供給頁的Response屬性的OutputStream。
(8)卸載階段。卸載頁屬性(如Response和Request)並執行清理。
在頁生命週期的每個階段中,頁將引發可運行自己的代碼進行處理的事件。對於控件事件,通過以聲明方式使用屬性(如onclick)或以使用代碼的方式,均可將事件處理程序綁定到事件。頁面還支持自動事件連接,即ASP.NET將尋找具有特定名稱的方法,並在引發特定事件時自動運行這些方法。如果@Page指令的AutoEventWireup屬性設置爲true(默認設置),頁事件將自動綁定至使用Page_event命名約定的方法,如Page_Load和Page_Init。
表19-5列出了最常用的頁面生命週期事件及其常規用途。
表19-5 頁面生命週期事件
頁面事件 |
常規用途 |
Page_PreInit |
1. 使用IsPostBack屬性確定是否是第一次處理該頁 2. 創建或重新創建動態控件 3. 動態設置主控頁 4. 動態設置Theme屬性 5. 讀取或設置配置文件屬性值 |
Page_Init |
讀取或初始化控件屬性 |
Page_Load |
讀取和更新控件屬性 |
各種控件事件 |
執行特定於應用程序的處理: 1. 如果頁包含驗證程序控件,請在執行任何處理之前檢查頁和各個驗證控件的IsValid屬性 2. 處理特定事件,如Button控件的Click事件 |
(續表)
頁面事件 |
常規用途 |
Page_PreRender |
對頁的內容進行最後更改 |
Page_Unload |
執行最後的清理工作,可能包括: 1. 關閉打開的文件和數據庫連接 2. 完成日誌記錄或其他特定於請求的任務 |
各個ASP.NET移動控件都有自己的生命週期,而且生命週期與頁面生命週期類似。例如,在相應的頁事件期間將調用控件的Init和Load方法。如果頁上包含控件,則將首先調用控件的Init方法,然後調用頁的Init方法。在調用控件的Load方法之前,應該先調用頁面的Load方法。
19.2.7 自適應錯誤報告
在移動Web應用程序中進行自定義錯誤報告的工作方式,與其在標準ASP.NET中的工作方式基本相同。同樣可以在web.config文件中,爲錯誤指定一組自定義頁。在發生錯誤後,ASP.NET檢查應用程序是否配置爲顯示自定義錯誤,並且檢查是否存在適當的錯誤頁。如果上述任何一種檢查的結果爲真,則ASP.NET重定向到該錯誤頁,並且傳遞包含原始URL的參數。
對於移動Web應用程序,ASP.NET使用一個由6個步驟組成的進程查找和報告錯誤,這一進程以產品安裝開始,一直延續到發送錯誤輸出:
(1)將HTTP模塊安裝到標準應用程序鏈中。此模塊(屬於System.Web.Mobile. ErrorHandlerModule類)爲應用程序的錯誤事件安裝事件處理程序。
(2)在頁生命週期內,如果頁級別發生異常,ASP.NET調用將該頁的OnError方法。因爲該頁是移動頁,所以將調用MobilePage中的重寫實現,而該重寫實現又調用所分配的頁適配器的HandleError方法。此適配器方法可以詳細報告錯誤,並返回一個指示錯誤已得到處理的值。如果它不這樣做,則繼續處理異常。
(3)ASP.NET自動使用自定義錯誤頁。
(4)ASP.NET調用在第1步中安裝的錯誤處理程序。如果目標設備是能夠呈現完整的ASP.NET生成的錯誤信息的HTML瀏覽器,則返回此方法。
(5)否則,該事件首先收集與異常有關的信息,然後該事件創建類System.Web.Mobile. UI.MobileControls.ErrorFormatterPage的內部定義的移動頁的實例,將數據綁定到所收集的數據,並且呈現結果。此頁負責生成簡潔的特定於設備的錯誤信息。
(6)因爲異常已被處理,所以該事件不返回HTTP錯誤狀態代碼。