ASP.NET MVC必須知道的那些事!
MVC的由來:
在MVC模式之前,View界面的呈現、用戶交互操作的捕捉與相應、業務流程的執行以及數據的存儲等都是在一起的,這種設計模式叫自治視圖。
這重設計模式主要存在三大弊端:
- 重用性:業務邏輯與UI是不相關的,如果將業務邏輯與UI綁定在一起,業務邏輯將無法被重用。
- 穩定性:業務邏輯、UI邏輯、視圖界面三者的穩定性不同,綁定在一起會由最差的部分影響到整體,即“短板理論”。(就像一個壞木桶里的水,會從缺口的最低處先流出來)
- 可測試性:當UI與邏輯部分綁定在一起,極大的增加了測試難度。
因此,為了解決這些問題,有人采用了關注點分離的原則,將視圖界面、業務邏輯、UI邏輯三者分離開,并采用合理的交互模式將他們之間的依賴度降到了最低。這種模式就是MVC。
什么是MVC模式:
MVC分別代表著Model、View、Controller,從人機交互的角度來說,View會捕獲到用戶的操作直接發給Controller,Controller會主動去完成相應的UI邏輯,但如果設計到了業務功能,
Controller還會調用Model來合作完成。在完成相應的UI邏輯后,Controller根據需要控制原View或者創建新的View對用戶操作予以響應。
什么是ASP.NET MVC:
一句話概括:ASP.NET MVC就是建立在ASP.NET平臺上,基于MVC模式的,Web應用框架。
詳細點說:ASP.NET平臺采用管道式設計,具有良好的擴展性。整個ASP.NET MVC框架就是通過自定義ASP.NET的HttpModule和HttpHandler這兩個核心組件而建立的。
注:MVC中的Model主要體現為維持應用狀態并提供業務功能,但ASP.NET MVC中的Model與之是不同的,后者僅僅是綁定到View上的數據而已,兩者并不是一回事,在學習理解過程中要格外注意,不要混淆。
ASP.NET MVC是如何運行的:
當一個用戶請求提交上來后,ASP.NET MVC會針對當前請求實施路由解析,解析的目標就是找到用戶需要的Controller并激活它,執行對應的Action方法,最終返回用戶需要的東西。
也就是說,當ASP.NET MVC接收到抵達的請求后,首要任務就是通過該請求解析得到對應的Controller和Action名稱,那么它是如何解析的呢?這就要了解一下Asp.Net MVC的路由系統了。
ASP.NET MVC路由系統:
路由是干什么的?
對于ASP.NET MVC應用來說,來自瀏覽器的請求總是指向定義在某個Controller類型中的某個Action方法,請求URL與目標Controller/Action之間的映射就需要路由來實現。
路由是如何工作的?
在ASp.NET MVC的App_Start文件夾的RouteConfig 中有如下一個靜態函數
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }
這就是一個路由注冊的過程,路由注冊的核心在于根據提供的路由規則(路由模板、約束、默認值等)創建一個Route對象,并將其添加到全局路由表中。
什么是全局路由表?它是做什么的?
全局路由表是由ASP.NET定義的,路由表中的每個Route對象包含一個路由模板,Controller和Action的名字以占位符的形式,即{controller}{action}的形式定義在模板中,對于
每一個抵達的HTTP請求,路由系統會遍歷路由表并找到一個具有與當前請求URL模式相匹配的Route對象,然后利用它解析出以Controller和Action名稱為核心的路由數據。
MapRoute()方法是做什么的?
這個方法的意義在于向路由系統中添加自定義的一個URL映射規則。怎么添加的呢?這是根據系統上下文中的RouteTable對象中的RouteCollection類型的屬性Routes,而在MapRoute()方法中的實現說白了就是根據參數生成Route對象,并且添加Route對象到服務器中。
簡單來說,這段代碼實現的功能就是按{controller}/{action}/{id}這種格式解析URL地址,得到對應的Controller和Action。如果沒有,則跳轉默認地址,即/Home/Index。
通過路由系統得到了需要的Controller和Action名稱后,接下來要做的就是激活Controller對象,執行Action方法了。
controller的激活:
Controller對象的激活是通過工廠模式實現的,在激活Controller的工廠中有一個IControllerFactory接口,該接口具有唯一方法CreateController,根據當前請求的上下文和通過路由解析得到的Controller名稱來激活相應的Controller對象。代碼如下:
Public interface IControllerFactory { IController CreateController(RequestContext requestContext, string controllerName); }
Action的執行:
Action的執行主要是通過Controller的基類ControllerBase中的Execute方法來執行的,如果目標Action方法返回類型為ActionResult,則還需要執行該ActionResult對象對當前請求予以響應。
在ASP.NET MVC框架中,兩種情況的執行都是通過ActionInvoke對象來完成的。
public interface IActionInvoker { void InvokeAction(ControllerContext controllerContext,string actionName); }
ActionInvoke對象中定義了一個接口IActionInvoker,該接口定義了唯一的方法InvokeAction,該方法第一個參數為當前Controller的上下文對象,第二個參數為需要激活的Action名稱。