ViewResult
之前已經分析了很多個Result,但是並沒有分析我們最常用的ViewResult。因為它牽扯到了Razor引擎,所以需要單獨的拿出來去講。
之前在學習的時候,老師總會和我們說當你的功力達到一定地步的時候回答別人的問題,你就可以用一切皆對象去回答。這真的很裝逼。那么問題來了。MVC中的視圖是cshtml,代碼也是一些html標簽。那么它是什么?
引用上面的一切皆對象,它是一個對象。一個類的實例。不信看圖
"windir"\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\700f6620\c210e54文件夾下會有一堆dll,再使用ILSpy反編譯一下
這是我們的index.cshtml視圖頁面,它變成了這個一個繼承自WebViewPage的類!重寫了父類的Execute方法,方法內部可能有一些亂,但是仔細一看,這不就是我們的html標簽嗎。一切都清晰了起來。這里值得一提的是我們的global.asax也會生成一個繼承自MvcApplication的類
我們使用視圖的時候很方便,可以在上寫面c#代碼。很容易的填充數據。那么它是怎么做到的?其中又有什么不為人知的秘密。且看原碼
這是View方法的源碼,可以看到構造了ViewResult的對象。向里面塞入了我們的mode,ViewData還有一個ViewRngineConllection也就是View引擎集合。里面有WebFormViewRngine和RazorViewRngline
然后走到了ViewResultBase類的ExecuteResult方法,這里會調用ViewResult子類的FindView方法。可以看到拿到的是RazorView。繼續往下走,開始實例化ViewContext對象和output一起Render(渲染)
渲染的過程還是值得一看的,這里再次進入Render方法,這里通過GetCompiledType反射構建了一個類,然后再實例化這個類。調用RenderView方法
在RenderView方法里面把我們的indexcshtml類轉成了WebViewPage,也就是它的父類,然后又開始填充ViewData,ViewContext等。下面有一個Inithelpers看的出來也就是初始化我們的@html,@ajax等。下面釋放內存轉到頁面。
下圖是全部的執行過程