ASP.NET由於採用了管道式設計,具有很好的擴展性,而整個ASP.NET MVC應用框架就是通過擴展ASP.NET實現的。通過上面對ASP.NET管道設計的介紹,我們知道ASP.NET的擴展點只要體現在HttpMoudle和HttpHandler這兩個核心組建之上,實際上整個ASP.NET MVC框架就是通過自定義的HttpMoudle(UrlRoutingModule)和HttpHandler(MvcHandler)實現的。爲了上讀者從整體上把握ASP.NET MVC的工作機制,接下來我按照其原理通過一些自定義組件來模擬ASP.NET MVC的運行原理,我們也可以將此視爲一個“迷你版”的ASP.NET MVC。值得一提的是,爲了讓讀者根據該實例從真正的ASP.NET MVC中找到對應的組件,我完全採用了與ASP.NET MVC一致的類型命名方式。[源代碼從這裏下載]
在正式介紹我們自己創建 的“迷你版”ASP.NET MVC的實現原理之前,我們不妨來看看建立在該框架之上的Web應用如何實現。我們通過Visual Studio創建一個空的ASP.NET Web應用(注意不是ASP.NET MVC應用),我們不會引用System.Web.Mvc.dll這個程序集,所以你在接下來的程序中看到的定義在該程序集中的同名類型都是我們自行定義的。
我們首先定義瞭如下一個SimpleModel類型,它表示最終需要綁定到View上的數據。簡單起見,同時也爲了驗證針對Controller和Action的解析機制,SimpleModel定義的兩個屬性分別表示當前請求的目標Controller和Action。
像真正的ASP .NET MVC應用開發一樣,我們需要定義Controller類型。如下面的代碼片斷所示,按照我們熟悉的命名方式(以字符Controller作爲後綴),我們定義瞭如下一個HomeController。HomeController實現的抽象類型ControllerBase是我們自行定義的。以自定義的ActionResult作爲返回類型的Index方法表示Controller的Action,它接受一個SimpleModel類型的對象作爲參數。該Action方法返回的ActionResult是一個RawContentResult對象,顧名思義,RawContentResult就是將指定的內容進行原樣顯示。在這裏我們將作爲參數的SimpleModel對象的Controller和Action屬性顯示出來。
ASP.NET MVC根據請求地址來解析出用於處理該請求的Controller的類型和Action方法名稱。具體來說,我們預註冊一些包含Controller和Action名稱作爲站位符的(相對)地址模板,如果請求地址符合相應地址模板的模式,Controller和Action名稱就可以正確地解析出來。和ASP.NET MVC應用類似,我們在Global.asax中註冊瞭如下一個地址模板({controller}/{action})。
在如上所示的用於進行地址模板註冊的Application_Start方法之中,我們還註冊了一個用於創建Controller對象的工廠。前面定義的HomeController定義在命名空間WebApp下,由於請求地址中只能解析出Controller類型的名稱,我們需要將該命名空間註冊爲當前ControllerBuilder的默認命名空間。RouteTable、ControllerBuilder和DefaultControllerFactory都是我們自定義的類型。
正如我上面所說,ASP.NET MVC是通過一個自定義的HttpModule實現的,在這個“迷你版”ASP.NET MVC框架中我們也將其起名爲UrlRoutingModule。在運行Web應用之前,我們需要通過配置對該自定義HttpModule進行註冊,下面是相關的配置。
到目前爲止,所有的編程和配置工作已經完成。爲了 讓定義在HomeController中的Action方法Index來處理針對該Web應用的訪問請求,我們需要指定與之匹配的地址(符合定義在註冊地址模板的URL模式)。如下圖所示,由於在瀏覽器中輸入地址(http://.../Home/Index)正好對應着HomeController的Index操作,所以對應的方法會被執行,而執行的結果就是將當前請求的目標Contrller和Action的名稱顯示出來。