在ASP.NET中用MSDNURLRewriting實現Url Rewriting (一)

 1.0.請一定要抱着批評的態度來看該文章
1.1. 概要
分析如何使用微軟提供的ASP.NET來對動態產生的URL地址進行網址重寫。網址重寫是實現一種截取網址請求並將其進行處理後重新指向到一個指定的網址的過程。作者本人在對各種實現網址重寫的技術進行研究和探討後得出的經驗和方法,希望能對您有所幫助。
1.2. 內容簡介
稍微花點時間看一看你做的網站裏頭的URL地址,你看到類似這樣的地址嗎http://yoursite.com/info/dispEmployeeInfo.aspx?EmpID=459-099&type=summary ?也許你會出於某種目的把大量的頁面文件從一個目錄甚至一個網站轉移到其他地方,而許多訪問者出於個人興趣或者研究目的之前就已經將原有網址收藏了起來, 如果這時他從收藏夾打開該頁面的時候發現這已經是壞鏈了。本文旨在介紹如何使用網址重寫將那些“難看”的網址轉換成比較有實際意義的網址,使其便於記憶。例如將http://yoursite.com/info/dispEmployeeInfo.aspx?EmpID=459-099&type=summary轉換成如下地址:http://yoursite.com/ dispEmployeeInfo/459-099/summary.html 。我們甚至發現網址重寫技術可以解決令人頭疼的404錯誤,或者說它可以創建一個智能化的404錯誤解決方案。
如上所述,網址重寫是實現一種截取網址請求並將其進行處理後重新指向到一個指定的網址的過程。在網址重寫執行的期間,相應處理程序處理被請求的網址,從中提取出相關的值,然後重新指向一個新的指定地址。例如:由於一次網站目錄調整,原有的 /people/ 子目錄下的所有網頁全部移動到/info/employees/目錄,原訪問者從收藏夾或者其他什麼地方點擊鏈接發出訪問/people/目錄下的文件的請求時,你肯定希望他還是能通過原有地址看到和原來相同的頁面,但實際上看到的卻是網址重寫指向的新目錄下的相應文件。
在老版本ASP中,使用網址重寫技術的途徑很少,要麼寫一個ISAPI過濾器,要麼購買第三方廠商提供的網址重寫組件,然而在微軟提供的ASP.NET下你可以通過多種方法很簡單地開發出自己的網址重寫軟件,以滿足自己各種不同的需要。本文將和你一起討論這門針對ASP.NET開發人員的實現網址重寫的技術,然後舉一些網址重寫實際應用的例子。在我們深入探討網址重寫技術的細節之前,我們先看一下日常使用網址重寫技術實現的場景。

1.3. 網址重寫的一般用途
創建一個數據操作的ASP.NET程序最常見的就是一個aspx頁面後面帶上一些查詢參數集合。例如在設計一個電子商務網站的時候,假定你設計了一項功能允許用戶瀏覽待售的商品,爲了更加方便操作,你設計了一個頁面displayCategory.aspx將商品按照給定的分類顯示,那麼該分類下的商品顯示頁面上應該在頁面文件對應網址後面加上了一個商品分類的查詢參數,例如用戶要查詢待售的“裝飾品”,在數據庫中所有的裝飾品數據對應的分類編號CategoryID的值爲5,那麼用戶會訪問如下網址:http://yoursite.com/displayCategory.aspx?CategoryID=5
創建一個包含類似這樣網址的網站最終有兩種結果,首先從最終用戶的角度來觀察,http://yoursite.com/displayCategory.aspx?CategoryID=5 這個網址有些雜亂,可行性分析專家Jakob Neilson(主頁:http://useit.com/) 建議選擇網址顯示方式時候考慮如下要求(參考網址:http://www.useit.com/alertbox/990321.html):
● 是否簡短
● 是否易於輸入
● 是否將站點結構形象化
● 是否具有隱蔽性,也就是讓用戶通過一個虛擬的看似有意義的導航地址訪問指向該地址
我想還應該在上述列表中再增加一條:是否便於記憶。http://yoursite.com/displayCategory.aspx?CategoryID=5 這個地址沒有一個地方符合Neilson標準的任何一條,也不便於記憶。當然,對於有經驗的網絡開發專家來說,他們很熟悉這種鍵值對構成的查詢參數結構體系,然而對於普通用戶來說輸入這些帶有參數的網址實在是太麻煩了。
一種較好的方法就是使用一種比較直觀且容易記憶的方式來將網址表示爲:http://yoursite.com/products/Widgets 乍一看很容易就會推斷這個網址所對應的內容極有可能會是顯示裝飾品(Widgets)信息,這個網址就變得更加容易記憶和傳播!然後我告訴我的同事:“請查看這個網址:http://yoursite.com/products/widgets ”不用我說第二遍,她可能一次就把地址敲到瀏覽器上了(你也可以在亞馬遜(Amazon.com)的網站上這樣嘗試一下)。很快就瀏覽器上就列出了裝飾品(Widgets)的內容。這裏“隱蔽性”表示:用戶可以自行變更網址的結尾,例如輸入:http://yoursite.com/products 就能看到全部分類相關的商品列表或者列出所有相關商品分類目錄列表。
注:用上述簡單的變更網址內容的方法來構思一下如今的比較流行的Blog網站生成的網址。例如:要查詢2004年1月28日所發的帖子,只需輸入 http://someblog.com/2004/01/28 即可,如果將網址裁減爲 http://someblog.com/2004/01 則顯示 2004年1月份的帖子 ,同樣將月份裁減掉得到 http://someblog.com/2004 則顯示出2004年全年所發的帖子。
網址重寫技術除了用於將複雜的網址簡單化之外,它還能用於處理因網站目錄調整或者其他原因導致產生大量的無效鏈接和過期書籤。
1.4. 當一個Web請求傳送到IIS會發生什麼?
在探討如何實現網址重寫這項技術之前,很有必要了解一下IIS是處理所接收的Web請求的機制。當一個Web請求到達IIS Web服務器時,IIS會根據所請求的文件後綴名來決定如何處理該請求,IIS可以處理諸如HTML頁面、圖片、靜態內容,或者將請求轉發給ISAPI應用程序,由該ISAPI應用程序處理後生成HTML靜態內容返回給IIS,最後由IIS將請求結果發送回給客戶端。(一個ISAPI應用程序就是一套編譯好能隨時在後臺運行的類庫,它的任務就是根據請求生成相關的內容。)
例如:如果IIS接收到一個對Info.asp的請求,它會將該請求轉交給asp.dll來處理,該ISAPI應用程序調出並執行所請求的ASP頁面,然後把生成的HTML代碼返回給IIS,IIS最後把內容發送回請求客戶端。對於ASP.NET頁面,IIS則將請求轉交給名爲aspnet_isapi.dll的ISAPI應用程序來處理,該ISAPI應用程序調用託管的ASP.NET工作進程來處理該請求,並將生成的HTML代碼返回給請求客戶端。
你可以自定義IIS,將某一類擴展名映射到指定的ISAPI應用程序,圖一顯示了IIS管理工具中的應用程序配置對話框。

圖一.已配置的文件擴展名映射

 

關於對IIS如何管理所接收的請求的詳細探討有些超出本文內容,想了解的更詳細的話可以參考Michele Leroux Bustamante的著作Inside IIS and ASP.NET(深入研究IIS與ASP.NET),重要的是要了解ASP.NET引擎只負責處理對擴展名已經被正確配置映射到aspnet_isapi.dll的網絡請求。

1.5. 用ISAPI過濾器來分析請求
除了將請求的文件擴展名映射到相應的ISAPI應用程序外,IIS還執行一些其他工作。例如IIS還主動對發出請求的客戶端用戶進行授權,並判斷已授權用戶是否對其請求的文件擁有訪問權限,在一個請求過程的全部生命期內,IIS的處理經歷了幾個階段,在每一個階段IIS都生成一個事件,而該事件可以被ISAPI過濾器實時操控的。
如同ISAPI應用程序一樣,ISAPI過濾器也是一塊塊安裝在Web服務器上的非託管代碼。ISAPI應用程序用於對所接收的特定文件類型做出響應,而ISAPI過濾器含有對IIS生成的事件做出響應的代碼(contain Code),甚至可以編輯進出的數據。ISAPI也含有衆多應用程序,包括:
· 權限控制與授權(Authentication and Authorization)
· 日誌記錄與監視(Logging and Monitoring)
· HTTP內容壓縮(HTTP Compression)
· 網址重寫(URL Rewriting)
本文所探討的用ASP.NET實現的網址重寫技術就是基於ISAPI過濾器用於網址重寫的技術內容,然而我們仍然要討論一下究竟是使用ISAPI過濾器還是使用ASP.NET應用程序提供的技術來實現網址重寫技術。


1.6. 當一個請求傳入ASP.NET引擎的時候會發生什麼?
ASP.NET問世之前,在IIS Web服務器上的網址重寫功能需要通過ISAPI過濾器來實現,自從這個傢伙問世後我們就能通過ASP.NET來實現URL重寫了,因爲ASP.NET的解釋引擎與IIS有極大的相似之處,產生這些相似性主要是因爲ASP.NET:
· 在處理接收的請求的生命期內也會產生事件;
· 允許任意數量的HttpModule操控產生的事件,這與IIS中的ISAPI過濾器類似;
· 將請求的資源委託給HttpHandler處理,這與IIS中的ISAPI應用程序類似。
和IIS一樣,在一個請求的整個生命期內,ASP.NET對該請求的處理狀態發出的狀態改變信號引發相應的事件。例如:BeginRequest事件在ASP.NET開始響應客戶端請求之始引發;AuthenticateRequest事件在ASP.NET確立用戶身份後引發,當然還有諸如AuthorizeRequest,ResolveRequestCache和EndRequest等其它很多事件,這些都是System.Web.HttpApplication類下的事件,更多信息請參考技術文檔中的類HttpApplication概要(HttpApplication Class Overview)。
如上所述,可以創建ISAPI過濾器並用於相應IIS引發的事件,同理,ASP.NET也提供了HttpModule用於響應ASP.NET引擎引發的事件,一個ASP.NET應用程序通過配置可以擁有多個HttpModule。ASP.NET引擎每處理一個請求,便初始化一個相應配置好的HttpModule,並允許它針對請求處理期間引發的事件生成相應的事件委託。事實上ASP.NET引擎處理每一個請求調用大量的事件委託。FormsAuthenticationModule就是衆多內嵌HttpModule中的一個,它首先檢查是否使用表單授權,如果是的話,它將檢查用戶是否已授權,如果沒有授權則自動把用戶重定向到指定的登錄頁面。
回憶在IIS中,一項請求最後被轉交給一個ISAPI應用程序處理,該應用程序針對每一項請求進行處理並返回相應的數據。例如,客戶端發出一個訪問經典ASP頁面的請求,IIS將該請求轉交給asp.dll程序處理,asp.dll針對該請求執行asp頁面內容,並返回HTML編碼。ASP.NET也使用了類似的手法,ASP.NET引擎在將這些HttpModule初始化後,判斷並決定調用相應的HttpModule來處理該請求。
所有通過ASP.NET引擎解析的請求最終被送交一個HttpHandler或者HttpHandlerFactory(一個HttpHandler只是簡單地返回一個用於處理該請求的HttpHandler的實例。)最終的委託呈現並響應所請求的HTML編碼,併發送回IIS,IIS則將HTML返回給請求客戶端。
ASP.NET包含許多HttpHandler,例如,PageHandlerFactory是用於呈現ASP.NET頁面內容,WebServiceHandlerFactory用於呈現ASP.NET Web服務的SOAP數據包,TraceHandler用於將ASP.NET請求資源的HTML標記寫入trace.axd。
圖二描繪了一個針對ASP.NET資源的請求所經過的處理流程。首先,IIS接收到該請求並將其轉交給aspnet_isapi.dll。其次,ASP.NET引擎將一些HttpModule初始化。最後,最終的HttpHandler被調用,生成相應的標記語言,並將其返回給IIS,最終返回到請求客戶端。

圖二.IIS和ASP.NET對請求的處理過程

1.7. 創建並註冊自定義HttpModule和HttpHandler
創建自定義HttpModule的工作相對較簡單,它包括一個實現當前接口的託管類,HttpModule必須實現System.Web.IHttpModule接口,同樣HttpHandler和HttpHandlerFactory必須分別實現System.Web.IHttpHandler接口和System.Web.IhttpHandlerFactory接口。有關創建HttpHandler和HttpModule的細節已經超出本書範圍,要了解更多詳情請參閱Mansoor Ahmed Siddiqui的文章《HttpHandlers and HTTP modules in ASP.NET》(ASP.NET中的HttpHandler和HttpModule)。
一旦HttpModule和HttpHandler被創建後,必須向Web應用程序註冊。如果要向整個Web服務器HttpModule和HttpHandler只需簡單的寫入machine.config文件;如果是由指定的Web應用程序調用則需在該程序的web.config配置文件中添加幾行XML標記。
例如,要向指定的Web應用程序註冊HttpModule和HttpHandler,只需向該Web應程序的web.config配置文件中configuration/System.Web節中添加下列幾行:

<HttpModules>
 <add type="type" name="name" />
</HttpModules>
其中type屬性爲HttpModule的標識號和類庫名稱,name屬性則爲該模塊取一個較爲友好的名稱方便在Global.asax調用。
HttpHandler和HttpHandlerFactory則是在web.config文件中configuration/System.Web節中添加<httpHandler>標記,例如:

<httpHandlers>
 <add verb="verb" path="path" type="type" />
</HttpModules>
回憶上文,ASP.NET對每一個接收到的請求指派相應的HttpHandler來處理並呈現相應內容,該指派決定於所接收請求的verb和path的內容,verb爲HTTP請求的類型:GET或者POST,path則爲請求的文件的路徑和文件名。如果我們打算用一個HttpHandler來處理所有GET類型和POST類型的並且文件擴展名爲.scott的內容,可以在web.config相應配置節中加入下列標記:

<httpHandlers>
 <add varb="*" path=".scott" type="type" />
</httpHandlers>
其中type是我們定義的HttpHandler的類型。
注意:在註冊HttpHandler的時候必須注意HttpHandler所使用的文件擴展名必須已經在IIS中做指向ASP.NET引擎的映射,在上面.scott擴展名的例子中,如果我們所使用的.scott擴展名如果沒有在IIS中做指向ASP.NET引擎的映射的話,假定對foo.scott文件發出請求,該請求將導致IIS將foo.scott文件內容直接呈現給客戶端,爲了能夠讓HttpHandler處理該請求,必須將.scott擴展名在IIS中做指向ASP.NET引擎的映射,之後IIS才能正確地將.scott的請求轉交給相應的HttpHandler。
有關HttpModule和HttpHandler更詳細的內容請參閱MSDN中<HttpModules>節和<httpHandlers>節的文檔信息。
<HttpModules>文檔參考;
<httpHandlers>文檔參考。

1.8. 實現網址重寫
網址重寫技術不但可以在IIS Web服務器一級通過ISAPI過濾器實現,而且還可以在ASP.NET一級通過HttpModule或者HttpHandler實現。本文主要關注在ASP.NET一級實現網址重寫技術,所以此時不必關注在ISAPI應用程序中實現網址重寫的技術細節,而且有很多第三方廠商提供的ISAPI過濾器,比如
Helicon的ISAPI Rewrite;
QwerkSoft的IIS Rewrite;Port80的PageXChanger;
等等。

1.9. 構建網址重寫引擎
在ASP.NET中實現網址重寫很簡單,只需調用System.Web.HttpContext類的RewritePath()方法即可。HttpContext類中包含有關於特定HTTP請求的HTTP規範信息。ASP.NET引擎每接收到一個特定請求後便針對該請求創建一個特定的實例,這個類包含一些屬性諸如:Request和Response屬性,分別提供對請求和響應的訪問;Application和Session屬性提供對Application變量和Session變量的訪問;User屬性提供對已授權用戶信息的訪問。
在微軟.NET Framework 1.0版本中,RewritePath()方法接收一個新路徑的簡單字符串,在其內部HttpContext類的RewritePath(string)方法內在地更新Request對象的路徑和查詢參數。除了RewritePath(string)方法之外,.NET Framework 1.1版還提供了另外一些重載版本,其中一個重載版本接收三個輸入字符串參數,這種交替的重載形式不僅僅只是設置Request對象的路徑和查詢參數這些屬性,而是設置更深層的成員變量,這些成員變量用於爲PhysicalPath、PathInfo、FilePath屬性計算Request對象值。
爲了實現ASP.NET中的網址重寫,我們需要創建一個HttpHandler和HttpModule用於:
 根據請求的路徑決定所需要重寫的路徑;
 重寫路徑,如果需要的話可以調用RewritePath方法;
以前文所構建的那個站點爲例,可以通過/info/employee.aspx?empID=EmployeeID來訪問每一個僱員的信息。爲了使這個網址更加地具有“隱蔽性”,我們可能會使用更加容易理解的訪問方式如:/people/僱員名.aspx。這裏就有了一個網址重寫的案例:當接收到對/people/ScottMitchell.aspx的請求的時候,我們就得使用網址重寫使得對該頁面的請求被重寫指向到先前使用的/info/employee?EmpID=1001地址。


本文來自: 腳本之家(www.jb51.net) 詳細出處參考:http://www.jb51.net/article/8035.htm

發佈了2 篇原創文章 · 獲贊 5 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章