上篇中對於視圖引擎只是作了簡單的演示,對於真正的理解視圖引擎的工做過程可能還有點模糊,本篇將會對由MVC框架提供給咱們的Razor視圖引擎的整個執行過程作一個粗略的講解,目的在於讓你們對Razor視圖引擎的執行過程留個印象以便聯想的思考到視圖引擎的做用以及視圖在MVC框架中的表示。html
你們看過上個篇幅對試圖引擎的執行過程有個大概的瞭解,而Razor視圖引擎的執行則更爲詳細,不會像上篇這麼粗糙,來看一下示意圖,圖1.app
圖1框架
圖1中所示的是Razor視圖引擎中的對象結構的繼承關係,對於圖1右邊部分的意思則是表示視圖引擎是從系統的ViewEngines.Engines也就是ViewEngineCollection集合類型中取出來的,在ViewEngineCollection下面部分則是表示Razor試圖引擎的一個繼承關係示意圖。ide
圖2工具
咱們先來看紅色指針所指部分的流程:ui
在咱們使用ViewResult做爲控制器方法的返回類型的時候,MVC框架會首先執行ViewResult中的FindView()方法,而在ViewResult的FindView()中並非由它自身來執行查找視圖的任務的,MVC框架不少管閒事,它會干擾進來。它會從系統的ViewEngines.Engines也就是ViewEngineCollection集合類型中取出來Razor試圖引擎來執行查找視圖的任務【圖1中例舉了Razor視圖引擎的繼承結構】。spa
隨之由VirtualPathProviderViewEngine類型來執行查找視圖的任務,實際在這裏根據視圖名稱查找的並非咱們定義的xxxx.cshtml視圖文件,而是由xxxx.cshtml文件編譯成的cs文件,這些cs文件中表示對應視圖的代碼,這個在本篇的最後會有講解,那麼這些cs文件是在何時生成的呢?是在請求到達控制器的時候,好事的MVC框架就會把View文件夾下或者是對應區域的View文件夾下,關於這個控制器文件夾中的全部視圖都會通通的編譯生成爲cs文件。指針
扯蛋扯遠了回到主題,在VirtualPathProviderViewEngine類型找到視圖後【cs文件】,便會讓RazorViewEngine類型來生成視圖處理類,也就是實現了IView的RazorView類型了而且封裝到ViewEngineResult類型實例中。調試
下面咱們就來講明下藍色指針所指部分的流程:code
這個時候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 hidden WriteLiteral("\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 hidden WriteLiteral(" <h3>ID: "); #line 8 "E:\JY\JY\Action\ASP.NET MVC\SystemCase\MyMvcApplication\MvcApplication\Views\iocdemo\Index.cshtml" Write(item.ID); #line default #line hidden WriteLiteral(" Name:"); #line 8 "E:\JY\JY\Action\ASP.NET MVC\SystemCase\MyMvcApplication\MvcApplication\Views\iocdemo\Index.cshtml" Write(item.Name); #line default #line hidden WriteLiteral("</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/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面