標籤:style blog http color 使用 strong
ASP.NET MVC
視圖
(
二
)
前言
上篇中對於視圖引擎只是做了簡單的示範,對於真正的理解視圖引擎的工作過程可能還有點模糊,本篇將會對由MVC架構提供給我們的Razor視圖引擎的整個執行過程做一個粗略的講解,目的在於讓大家對Razor視圖引擎的執行過程留個印象以便聯想的思考到視圖引擎的作用以及視圖在MVC架構中的表示。
ASP.NET MVC
視圖
- 自訂視圖引擎
- Razor視圖引擎執行過程
- Razor視圖的依賴注入、自訂視圖輔助器
- 分段、分部視圖的使用
- Razor文法、視圖輔助器
Razor視圖引擎執行過程
大家看過上個篇幅對試圖引擎的執行過程有個大概的瞭解,而Razor視圖引擎的執行則更為詳細,不會像上篇這麼粗糙,來看一下,圖1.
圖1
圖1中所示的是Razor視圖引擎中的對象結構的繼承關係,對於圖1右邊部分的意思則是表示視圖引擎是從系統的ViewEngines.Engines也就是ViewEngineCollection集合類型中取出來的,在ViewEngineCollection下面部分則是表示Razor試圖引擎的一個繼承關係。
圖2
我們先來看紅色指標所指部分的流程:
在我們使用ViewResult作為控制器方法的傳回型別的時候,MVC架構會首先執行ViewResult中的FindView()方法,而在ViewResult的FindView()中並不是由它自身來執行查詢檢視表的任務的,MVC架構很多管閑事,它會干擾進來。它會從系統的ViewEngines.Engines也就是ViewEngineCollection集合類型中取出來Razor試圖引擎來執行查詢檢視表的任務【圖1中例舉了Razor視圖引擎的繼承結構】。
隨之由VirtualPathProviderViewEngine類型來執行查詢檢視表的任務,實際在這雷根據視圖名稱尋找的並不是我們定義的xxxx.cshtml視圖檔案,而是由xxxx.cshtml檔案編譯成的cs檔案,這些cs檔案中表示對應視圖的代碼,這個在本篇的最後會有講解,那麼這些cs檔案是在什麼時候產生的呢?是在請求到達控制器的時候,好事的MVC架構就會把View檔案夾下或者是對應地區的View檔案夾下,關於這個控制器檔案夾中的所有視圖都會統統的編譯產生為cs檔案。
扯蛋扯遠了回到主題,在VirtualPathProviderViewEngine類型找到視圖後【cs檔案】,便會讓RazorViewEngine類型來產生視圖處理類,也就是實現了IView的RazorView類型了並且封裝到ViewEngineResult類型執行個體中。
下面我們就來說明下藍色指標所指部分的流程:
這個時候MVC架構會調用ViewEngineResult類型中的View屬性中的Render()方法,實則就是剛剛上面說的RazorView類型執行個體中的方法。
然後我們看圖2,在Render()方法的執行過程中,首先是由BuildManagerWrapper類型根據視圖的路徑去讀取檔案並且動態編譯過後返回視圖cs檔案中所表示的類型,這裡BuildManagerWrapper類型是MVC架構的內部類型是實現了內部的IBuildManager介面,BuildManagerWrapper類型的意思就是對於動態編譯功能的一個封裝,實則就是調用System.Web.Compilation.BuildManager裡的功能。
回到主題,類型產生好了過後是由DefaultViewPageActivator類型來產生視圖所對應的C#類型【System.Web.Mvc.WebViewPage<dynamic>】,最後通過RazorView類型中的RenderView()方法來對剛剛我們產生好的視圖對應的C#類型進行基礎性的賦值,比如說從ViewContext型別參數中擷取ViewData、ViewBag等等資料資訊【ViewContext類型繼承自ControllerContext,所以你懂的】進行賦值。
最後會被WebPageRenderingBase類型的對象來做渲染處理,這部分內容就不做闡述了。
以上就是多Razor視圖引擎也就是ViewResult類型的處理過程,說的很粗糙大家見諒希望能對大家對於視圖的理解上有所協助。
下面來說一下由MVC架構對於視圖檔案編譯後的cs檔案,要眼見為實嘛對吧。
首先我們看一下某個視圖的啟動並執行結果,圖3.
圖3
而對應的視圖代碼【cshtml檔案中的代碼】,如代碼1-1.
代碼1-1
@{ ViewBag.Title = "Index";}<h2>Index</h2>@foreach (var item in Model){ <h3>ID: @item.ID Name:@item.Name</h3>}
那麼在請求達到控制器過後編譯後的視圖cs檔案存在哪了呢?
在系統的C:\Users\你系統的使用者名稱\AppData\Local\Temp\Temporary ASP.NET Files中,當然了並不是在這個檔案夾下面,而是在會這裡又產生一些其它的亂七八糟名稱的檔案夾,找一個即可。
我就是在C:\Users\你系統的使用者名稱\AppData\Local\Temp\Temporary ASP.NET Files\root\19537580\dfb4a136檔案夾下找的,當然了cs檔案的命名也不是對應著視圖名稱的,一般是由App_Web開頭命名的。經過一番尋找找到了對應代碼1-1的cs檔案了,來看一下,代碼1-2
代碼1-2
#pragma checksum "E:\JY\JY\Action\ASP.NET MVC\SystemCase\MyMvcApplication\MvcApplication\Views\iocdemo\Index.cshtml" "{406ea660-64cf-4c82-b6f0-42d48172a799}" "11002EF3288CEAD21A96AC68FD35C045"//------------------------------------------------------------------------------// <auto-generated>// 此代碼由工具產生。// 運行時版本:4.0.30319.1008//// 對此檔案的更改可能會導致不正確的行為,並且如果// 重建代碼,這些更改將會丟失。// </auto-generated>//------------------------------------------------------------------------------namespace ASP { using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Web; using System.Web.Helpers; using System.Web.Security; using System.Web.UI; using System.Web.WebPages; using System.Web.Mvc; using System.Web.Mvc.Ajax; using System.Web.Mvc.Html; using System.Web.Routing; public class _Page_Views_iocdemo_Index_cshtml : System.Web.Mvc.WebViewPage<dynamic> { #line hidden public _Page_Views_iocdemo_Index_cshtml() { } protected ASP.global_asax ApplicationInstance { get { return ((ASP.global_asax)(Context.ApplicationInstance)); } } public override void Execute() { #line 1 "E:\JY\JY\Action\ASP.NET MVC\SystemCase\MyMvcApplication\MvcApplication\Views\iocdemo\Index.cshtml" ViewBag.Title = "Index"; #line default #line hiddenWriteLiteral("\r\n<h2>Index</h2>\r\n"); #line 6 "E:\JY\JY\Action\ASP.NET MVC\SystemCase\MyMvcApplication\MvcApplication\Views\iocdemo\Index.cshtml" foreach (var item in Model){ #line default #line hiddenWriteLiteral(" <h3>ID: "); #line 8 "E:\JY\JY\Action\ASP.NET MVC\SystemCase\MyMvcApplication\MvcApplication\Views\iocdemo\Index.cshtml" Write(item.ID); #line default #line hiddenWriteLiteral(" Name:"); #line 8 "E:\JY\JY\Action\ASP.NET MVC\SystemCase\MyMvcApplication\MvcApplication\Views\iocdemo\Index.cshtml" Write(item.Name); #line default #line hiddenWriteLiteral("</h3>\r\n"); #line 9 "E:\JY\JY\Action\ASP.NET MVC\SystemCase\MyMvcApplication\MvcApplication\Views\iocdemo\Index.cshtml"} #line default #line hidden } }}
想必看到這裡大家清楚了吧,對於視圖檔案cshtml、vbhtml等等最後在運行時編譯成的類型System.Web.Mvc.WebViewPag,至於類型後面的泛型型別是dynamic類型是對應於普通視圖,而強型別視圖編譯後的類型就會將此處的dynamic類型替換成強型別視圖的ViewModel類型了,最後說一下對於#line的意思可問度娘,是便於我們調試用的。
金源
出處:http://www.cnblogs.com/jin-yuan/
本文著作權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面