之前覺得這個話題已經被談濫了URL Rewrite早已經被廣大開發人員所接受網上關於URL Rewrite的組件和文章也層出不窮但是總是讓我感覺意猶未盡於是最終還是忍不住提筆寫了這系列文章這些文章不會談論URL Rewrite的價值與意義而只會談論純技術的內容文章中也不會有詳盡地實現分析而是結合了我的經驗從應用角度來講解這個話題您已經知道的您還不知道的別處已經講過的或者還沒有講過的希望這系列文章的舊事重提不會讓您覺得沉悶並且能讓您了解ASPNET中URL Rewrite的方方面面如果您以後再遇到URL Rewrite方面的問題是能夠想到這幾篇文章估計我做夢也會笑出聲來
要充分理解文章後面談到的話題我們必須簡單的了解一下IIS與ASPNET的通信過程我在這裡講解的是IIS 服務器至於IIS 和IIS 前者可以說已經被淘汰了而後者的經典模式與IIS 可謂如出一轍而新的管道模式其實是講ASPNET中的某些概念與IIS進行了深度集成我相信如果您了解了IIS 和ASPNET在IIS 的集成模式下也不會有任何問題
首先我們來看一幅簡單的示意圖展示了IIS從收到Request開始到返回Response整個過程中的幾個主要步驟
IIS收到請求
選擇器根據URL的特點與IIS中的配置選擇一個ISAPI用於處理該請求——現在自然會選擇ASPNET ISAPI
ASPNET執行引擎接收到請求於是初始化數據(例如構建各種對象)
開始觸發各種Pipeline事件自然先從BeginRequest開始
經過了多個Pipeline事件ASPNET根據配置為當前請求選擇一個合適的Handler或HandlerFactory進行處理(當然特殊情況例外例如已經在之前的事件中直接輸出結果並結束請求了)
經過了Handler處理之後又經過幾個Pipeline事件以EndRequest結束
輸出Response
在一個ASPNET應用中如果要進行URL Rewrite那麼一般就是在BeginRequest事件中調用HttpContext的RewritePath方法將該請求重新定位至一個目標URL例如我們就可以在Globalasax中重寫Application_BeginRequest方法來實現這一點
之所以在BeginRequest中進行Rewrite是因為這個事件是在所有Pipeline事件中最早被觸發的在這時進行了重新定位之後當前HttpContext中的一些屬性也就發生了相應的變化(例如HttpContextRequestPath)這樣接下來的Pipeline事件的處理程序邏輯就會受到影響例如在需要根據目錄進行權限判斷時就會使用定位後的路徑而不是ASPNET所收到的請求自然最顯著的變化就是對Handler的選擇例如上例我們把請求重新定位至CustomerListaspx文件這樣ASPNET引擎就會選擇*aspx所對應的SystemWebUIPageHandlerFactory類對請求進行處理
public class Global : System
Web
HttpApplication
{
protected void Application_BeginRequest(object sender
EventArgs e)
{
HttpContext context = HttpContext
Current;
if (context
Request
Path
Equals(
/Customers
StringComparison
InvariantCultureIgnoreCase))
{
context
RewritePath(
~/CustomerList
aspx
);
}
}
}
最後插句提外話有兩個概念需要區分開來那就是ASPNET Pipeline與Web Forms兩者都是ASPNET裡的重要模型但是差別還是非常大的
◆ASPNET Pipeline作為每個ASPNET應用所接受到的請求來說都會經過這個管道進行處理這是一個ASPNET級別的模型
◆Web Forms在ASPNET Pipeline的執行過程中其中有一個步驟是選擇一個合適的Handler(或HandlerFactory)來處理請求如果是aspx頁面ASPNET就會選擇SystemWebUIPageHandlerFactory類在這個類中才最終形成了WebForms模型
其實上面這句話的形成二字可能也不太確切因為Web Forms可能應該是一個可以獨立使用的執行引擎和模型而SystemWebUIPageHandlerFactory中也只是利用了這個模型而已我們在編寫ASPNET應用時完全可以根據我們的需要在其他地方使用這個模型
From:http://tw.wingwit.com/Article/program/net/201311/15295.html