前言
大家好,我是大成子。之前有朋友去面試,面試官問了一個這樣的題:在http://ASP.NET MVC 中視圖和控制器之間有哪幾種數據傳遞方式?今天大成子就帶大家一起來探討C(控制器)向V(視圖)【前端視圖向控制器發送請求傳輸的數據的方式本次這里不做贅述了,有機會再做分析和分享】傳輸數據有哪幾種方式。(ViewData/ViewBag/TempData/model)
ViewData
第一個是ViewData,它用來存儲存儲String Key/Object的值。它是一個繼承自ViewDataDictionary類的Dictionary對象,用來從Controller中的Action向對應的View傳遞數據。注意:ViewData只能在本控制器本action中向對應的視圖傳遞數據,生命周期和View一樣,如果有重定向,則ViewData存儲的數據會丟失變成Null。在取出的時候要注意類型的適當轉換。下面我們通過代碼來看看ViewData的使用。

新建一個Core Web應用程序,起名為ControllerToView

選擇MVC模板,取消https配置,選擇不進行身份驗證


格式:ViewData["key"]=value,如上兩圖所示,我在Home控制器的Index動作方法當中定義了一個用來存儲用戶名的ViewData,在視圖中用Razor語法@加C#代碼,可以通過鍵的方式取出Action中存儲的數據並輸出,如下圖所示:

前面我有講過,ViewData存儲簡單,但是取出的時候是要進行數據轉換的,這里的string或者int類型只不過自動轉換了,那假如我要傳輸一個對象的集合怎么辦呢?下面我們來看看

上圖為數據集的初始化,注意:其實根據面向對象OOP的對象單一職責和迪米特法則,我的實體類和業務邏輯是不應該寫在控制器當中的,我這里是為了方便講述。大家實際開發當中還是要有良好的代碼規范和習慣的,不要學我(#^.^#)


取出數據集,並在前端循環輸出,很明顯,報錯了,它的意思是說這個object它識別不了,不能循環遍歷。我們做一下類型轉換,注意:頂部引入Student類所在的命名空間,如下圖:

頁面結果如下:

前面講過:ViewData、ViewBag等這種傳輸方式,可以直接用(他們都是父類Controller的成員),並且只能向本控制器的本動作方法對應的視圖傳輸數據,如果重定向,則數據會丟失,下面我們來試驗一下:


新建另一個控制器DataPass,在Index中初始化儲存ViewData pwd的值,並重定向到Home/Index,在Home的index視圖中顯示數據。啟動程序,在瀏覽器中輸入/DataPass/Index,如下圖所示

它會重定向到Home/Index的視圖當中去:

並沒有傳過來。下面再試試跨視圖看是否能傳輸,

在Home控制器任意非Index的動作方法中定義pwd的數據存儲,測試結果顯示還是沒有顯示.我們再在Index中定義,這時頁面顯示有數據!


ViewBag
第二個是ViewBag,它是一個動態類型變量(dynamic),這是C# 4.0引入的新特性,變量類型會在運行時進行解析。它里面其實有ViewData的包裝,也用於C向V傳遞數據。同樣,它的生命周期也和當前的Action同存亡,重定向或者請求結束,它的使命也就結束了。由於它是動態類型變量,所以在取出數據的時候不需要進行類型轉換!下面演示一下:


測試結果如下圖:

TempData
第三個則是TempData,它是一個繼承自TempDataDictionary類的字典對象,它默認情況下是基於Session存儲機制之上的,它與Session的區別就在於,TempData取了一次之后,就會自動銷毀,而Session是有時長有效期的,在有效期內可以無限使用。TempData可以跨控制器、Action傳輸數據,你可以在其他地方定義,等需要用的時候去尋找,儲存,並在需要的視圖中展示,關於TempData的演示,我這里就不做演示了。
model
在控制器中還可以將數據模型,在返回視圖的時候給傳輸過去。



注意用model傳給動作方法對應的視圖時,要在頁面聲明model的數據類型,不然無法解析。如下圖所示:

End
好了本篇的學習就到這里了,還有任何交流和補充歡迎私信小編。看一萬遍,不如自己手動敲一遍。
歡迎關注微信公眾號:dotNET學習天地
期待您的交流,願共同進步。
