今天周一又沒什么事情要做,明天要去一家公司面試.Net,其實心里也沒底,別人會問什么問題。今天寫這篇文章是為了舒緩下心里壓力,接着上一章我們談的ASP.NET MVC技術來談。本文章其實不屬於理論教程類型,主要還是偏向於怎么去做以示例為主,只是在每一章節中把個人論點談一談,然后在寫一個代碼演示。廢話說完了,來看看講講什么把。
---------------------------------------------------------------------------------------------------------------------------------
上一章節我們介紹了下ASP.NET MVC層次結構和MVC這個技術上的介紹,接下來我要補充上一個章節忘記講述的ASP.NET MVC的頁面生命周期。
今天主要安排是這樣的,首先我們補充上一節遺漏的技術點。主要講解如下:
1)頁面生命周期
2) URL路由
3)MVC和WebForms本質上區別
4)代碼演示
一、頁面生命周期
1.在MVC中跟傳統的WebForms是不一樣的,微軟為了讓前后台進行代碼分離做個不少功夫,首先呢?我先說說傳統的WebForms是什么樣的頁面生命周期。WebForms頁面生命周期主要分2個方向我們討論(事件、頁面流程)
1)頁面事件
當我們看VS工具時候有很多人根本就沒考慮過VS為我們做了什么事。VS其實它在按F5運行頁面的時候為我們做個這樣的幾個事情(1:Page_PreInit、2:Page_Init、3:Page_Load、4:Page_PreRender、5:Page_UnLoad)這個WebForms事件有很多人都沒想過。接下來我們談每個事件它做了寫什么。1、Page_PreInit主要是負責事件是在頁生命周期的早期階段中可以訪問的事件。在PreInit事件后,將加載個性化信息和頁主題。2、Page_Init主要是負責服務器控件應執行任何創建和設置實例所需的初始化步驟。在該事件內無法使用視圖狀態信息;它尚未填充。在該事件的生存期內不應訪問其他服務器控件,不論它是此控件的子級還是父級。3、Page_Load主要是負責通知服務器控件執行任何設置為在每次頁請求時發生的處理步驟。可以訪問該事件的視圖狀態信息和 Web 窗體 POST 數據。還可以訪問頁控件層次結構內的其他服務器控件。4、Page_PreRender主要是負責使用該事件在服務器控件呈現給頁之前執行任何更新。在該事件的生存期內可以保存服務器控件視圖狀態的任何更改。不保存呈現階段內所做的同樣更改。5、Page_UnLoad主要是負責在卸載實例前,服務器控件必須在控件生命期的此階段執行所有最后的清理操作,如關閉文件、關閉數據庫連接和丟棄對象。
2)頁面流程
圖解如下:
1.請求頁
請求頁發生在頁生命同期開始之前。當用戶請求時,ASP.NET將確定是否需要分析和編譯頁面,或者是否可以在不運行頁的情況下輸出頁面緩存來進行響應。后者是通過處理@OutputCache指令來控制頁面緩存策略的。
2.開始
這個階段用於初始化頁面類的屬性。用於處理用戶的請求還有要回發數據庫的響應的對象,Request和Response就在這個過程中設置,還根據是回發請求還是新的請求來設置IsPostBack屬性,這些屬性對於后面的操作是必須的。
3.頁面初始化
對應的是Page_PreInit事件。頁面初始化期間可以使用控件,並將設置每個控件的UniqueID屬性。此外,任何主題都將應用於頁。如果當前請求是回發請求,那么我們不能在這個階段獲取控件的屬性,因為此時控件屬性值還未從ViewState中還原。
在這個頁面級的事件中,所有在設計時創建的控件都將被用默認值做初始化。例如,如果你有一個Text屬性值為”Hello”的TextBox控件,則此時這個屬性被設置。這個事件僅僅發生在頁級別的類中,用戶控件和母版頁沒有這個事件,而動態設置頁面主題也只能在這個事件中進行。
4.控件加載
其對應的是Page_Init事件。在Page_Init事件中,讀取或者初始化控件的屬性,如果當前請求為回發請求,則將使用從視圖狀態和控件狀態恢復的信息加載控件屬性。
5.驗證
在此步驟中,將調用所有的驗證程序控件的Validate()方法,此方法將設置各個驗證程序控件和頁面的IsValid屬性。
6.頁面加載
與其對應的頁面事件是Page_Load事件。在Page_Load事件中,可以讀取和更新控件屬性,一般頁面的加載都放在這個事件中去處理。有些人認為這就是Page類第一個觸發的方法。這個方法是混淆我們Page生存周期的罪魁禍首之一。
注意:如果頁面是回發(PostBack)的話,在Page_Load之前還會有兩個進程:
加載視圖狀態:在這個事件中運行時隱藏域中分解出視圖狀態並加載到所有啟用了視圖狀態的控件中。
加載回發數據:在這個事件里實現了IPostBackDataHandler接口的控件從HTTP的Post數據中得到值。注意,TextBox控件不能從視圖狀態中獲得值,而是在此事件中從Post數據中獲取得值。
7.回發事件處理
如果當前請求是回發請求,則ASP.NET將會調用所有的事件處理程序。在這個上步驟中ASP.NET將會根據事件源調用不同的事件處理委托方法來處理請求。我們將在后面的ASP.NET事件模型中詳細介紹。需要注意的是,事件處理(比如像Button1_Click()之類的)是定義在ASPX頁面中的,有一些開發人員認為當單擊一個按鈕后會立即觸發Button1_Click(),其實在這個事件觸發之前首先要觸發Page_Load。
8.呈現
在這個步驟中,ASP.NET將會處理當前的視圖狀態,並將其序列化保存到頁。接着調用每個控件,將其呈現通過Response.OutputStream輸出。
9.卸載
在頁面完全呈現並准備丟棄時,將調用卸載,對應Page_Unload事件。在這個步驟中,將卸載Page實例並執行清理,包括如關閉打開的文件和數據庫連接,完成日志記錄或者其他任務。
2.MVC頁面生命周期
1)創建RouteTable
當ASP.NET 應用程序第一次啟動的時候才會發生第一步。RouteTable把URL映射到Handler。
2)UrlRoutingModule 攔截請求
第二步在我們發起請求的時候發生。UrlRoutingModule攔截了每一個請求並且創建和執行合適的Handler 。
3)執行MvcHandler
MvcHandler 創建了控制器,並且把控制器傳入ControllerContext,然后執行控制器。
4)執行控制器
控制器檢測要執行的控制器方法,構建參數列表並且執行方法。
5) 調用RenderView 方法
大多數情況下,控制器方法調用RenderView()來把內容呈現回瀏覽器。Controller.RenderView() 方法把這個工作委托給某個ViewEngine 來做。
MVC流程圖
二、URL路由
使用默認路由表
當你創建一個新的ASP.NET MVC 應用程序,應用程序已經配置了默認的URL路由。URL路由在兩個地方設置。
第一,URL路由配置在你的應用程序WEB配置文件中(Web.config文件)。文件中有四個有關路由的配置節:system.web.httpModules節,system.web.httpHandlers節,system.webserver.modules節,和system.webserver.handlers節。小心不要刪除這些配置節,因為沒有這些配置節路由將不在工作。
第二,更為重要的是,一個路由表在應用程序的Global.asax文件中創建。Global.asax文件是一個特別的文件,它包含了ASP.NET應用程序生命周期事件處理。當Application Start事件開始,路由被創建。
-
routes.IgnoreRoute:IgnoreRoute()是RouteCollection路由表類的擴展方法,用於忽略指定的路由請求。這句意思是忽略對擴展名為.axd文件的請求。
routes.MapRoute:MapRoute()方法是一個添加路由映射的方法(RouteCollection類的擴展方法)。這里是它最常用的一個重載,映射指定的 URL 路由並設置默認路由值:
1、"Default"是路由的名稱,這個名稱在應用程序的路由的集合(routes對象)中是唯一的,如果重名生成時就會報錯。
2、"{controller}/{action}/{id}"代表的是路由的 URL表達式。
3、 new { controller = "Home", action = "Index", id = UrlParameter.Optional } 聲明了一個包含路由值的object匿名對象。
三、MVC和WebForms本質上區別
以上我們討論了MVC路由和生命周期,接下來創建一個Controller,我在這里創建這個控制器想說明的是所有的MVC是基於Controller里面的Action,而在WebForms里面所有的操作都是基於事件驅動。(補:在這里創建的自定義Controller如果是繼承的是Page類的話,那么此處的MVC將會別手動改變成WebForms模式)
四、代碼演示
此處我演示的例子是自定義的Controller和如何修改Global.asax.cs文件,此功能為Action來檢測簡單信息
演示步驟如下:
創建Login控制器是用於,當數據提交到后台使用,並要修改方法,因為VS自動生成的是Index,而我這里是IsAdmin頁面。
創建IsAdmin視圖,用於展示UI給用戶
完整以上幾步必須修改Global.asax.cs,因為之前VS創建的路由為Home控制器 Index視圖。我們這里這樣寫的原因是,因為我要說明怎么修改路由。
修改前
修改后
以上只是展示這些代碼。提供 代碼下載