這篇來簡單說明一下Controller是怎麼傳資料給View的,至於View要如何取得資料並呈現的部分會在後天幾天有更詳盡的說明,這篇就著重在如何傳值給View。
一樣透過觀察MVC4的預設範本,開啟HomeController會發現裡面的Index、About與Contact Action裡面都有使用到ViewBag這個屬性,究竟這跟傳值給View有什麼關係呢,就讓我們一起看下去。
透過F12移至定義之後會看到ViewBag是動態型別,也就是說如果有錯誤的話只能在執行時期發現。
使用方式如下View.屬性名稱
ViewBag.Message="Your app description page.";
再來我們來觀察一下View是如何取得ViewBag的資料,可以直接開啟Views/Home/About.cshtml,或是在Action內案右鍵選擇移至檢視
在下圖我們可以看到設定值跟取值的方式是一樣的,都是ViewBag.屬性名稱,最前面的@是Razor的語法,這篇先暫時不說明,後面幾天會再提到
瀏覽About頁面時會看到Message值被顯示了,所以透過這個例子就可以看到Controller是如何透過ViewBag傳值給View
除了可以透過ViewBag傳值給View還有以下這幾種屬性可以運用
ViewDataDictionary是繼承IDictionary<string, object>,表示我們可以透過key-value的方式去設定或取值。
使用方法如下 ViewData["Key名稱"]
ViewData["Message"]="Your app description page.";
我個人是喜歡用ViewBag,因為只要夠過.就可存取屬性值,用ViewData還要打[""]就覺得比較麻煩,也因為這邊都是弱型別就沒有lntelliSense了,所以更懶得打字。
在這邊特別說明一下ViewBag與ViewData都不能跨Action傳值,如果要跨Action傳值可以使用TempData
TempDataDictionary是繼承IDictionary<string, object>,使用方式跟ViewData是一樣的,差別在於TempData是把資料存在Session中,所以才能跨Action傳遞資料,需要特別注意的是被寫入的資料在第一次讀取的時候就會被刪除了,所以才叫TempData
如果想要保留TempData的話可以使用Keep兩個多載方法來設定
使用強型別來傳遞資料,我們可以觀察AccountController裡面名稱為Register的Action發現最後return View()時多傳了一個model
再切換到Register.cs.html發現最上面有一行@model開頭的程式碼,這邊其實就是在將傳遞過來的資料轉型成@model指定的RigisterModel型別,這樣變成強型別之後才會有IntelliSence
好,講到這邊還是都沒提到ViewData.Model要怎麼用阿?其實ViewData.Model要做的事情已經被return View(model)做掉了,如果要使用ViewData.Model來傳遞的話請改寫成下方黃框程式碼即可
ViewData.Model=model;
return View();
如果想要讓Account/Register頁面發生錯誤,請註冊兩個一樣的帳號,這樣就可以測試使用ViewData.Model傳遞model的情況囉。