控制器與檢視資料傳送 - ViewData

ASP.NET Core Web 應用開發–使用 MVC 框架 / PART II MVC 的細節 / 控制器與檢視資料傳送 / 控制器與檢視資料傳送 - ViewData

ViewData是另外一種支援控制器與檢視資料傳輸的物件,以相同的書籍資料,再透過ViewData進行設定來作比較,以下是另外一組動作方法:

public IActionResult ServerTimeViewData()
{
    ViewData["ServerTime"] = DateTime.Now.ToShortTimeString();
    ViewData["Title"] = "Entity Framework Core 實務精要";
    ViewData["Price"] = 860;
    ViewData["Pdate"] = "2021 /9/15";
    return View();
}

其中以ViewData取代ViewBag,由於ViewData是key/value格式,因此原來於ViewBag中的屬性名稱,這裏調整為識別key值,同樣的,在對應的檢視檔案中以相同的格式處理,開啟檢視檔案ServerTimeViewData.cshtml,配置以下的內容:

<p><span>伺服器時間</span><span>@ViewData["ServerTime"]</span></p>
<p><span>書名:</span><span>@ViewData["Title"]</span></p>
<p><span>價格:</span><span>@ViewData["Price"]</span></p>
<p><span>出版日期:</span><span>@ViewData["Pdate"]</span></p>

這會得到與ViewBag相同的輸出結果。

從上述的示範可以看到ViewData是字典型態的集合物件,支援以key/value格式進行資料存取, ViewBag實際上是進一步封裝ViewData的功能以支援動態屬性的建立與存取,事實上兩者內部共用相同的一組字典集合,因此設定的資料彼此可以互相存取,甚至設定相同的key或是屬性時,後來的設定會覆蓋原來的值,以上述的設定為例,

public IActionResult ServerTimeViewData()
{
    ViewData["ServerTime"] = DateTime.Now.ToShortTimeString();
    ViewData["Title"] = "Entity Framework Core 實務精要";
    ViewData["Price"] = 860;
    ViewData["Pdate"] = "2021 /9/15";
	ViewBag.Price = 990 ; 
    return View();
}

最後引用ViewBag.Price將其設定為990,重新載入檢視檔案,可以看到價格部份的輸出為990。

若是在檢視檔案重新以ViewBag引用相關的屬性,同樣可以順利取得ViewData的設定。

ViewBag與ViewData另外還有一個差異在於型別資訊,前者是動態屬性,於執行期決定其值的型別,後者是object,如果要以指定型別取得其值必須明確轉型,例如以下兩行程式碼,分別以ViewBag與ViewData取出Price:

int price = ViewBag.Price;
int pricedata = ViewData["Price"] ;

第一行可以正確編譯,第二行則會出現錯誤,要求完成轉型,重新調整如下:

int pricedata = (int)ViewData["Price"];

接下來就可以順利通過編譯

類別物件存取

除了整數、字元等等的簡單型別資料,無論 ViewData 或是 ViewBag,同時可以直接指定類別物件,例如以下的配置:

public IActionResult ViewClass() { KTBook ktbook = new KTBook { BookId = 10010, Title = "商業級 ASP.NET MVC 樣式與架構實務", ISBN = "9789869347518", PublicationDate = new DateTime(2019, 5, 30), Price = 550, Pages = 320 }; ViewBag.book = ktbook; ViewData["ktb"] = ktbook; return View(); }

這段程式碼是一個ViewClass動作方法,首先建立KTBook物件,並逐一設定屬性名稱,然後設定給ViewBag.book屬性,另外以「ktb」為識別鍵值名稱,設定給ViewData,然後回傳對應的檢視檔案。

在檢視檔案ViewClass.cshtml當中,以Title屬性為例,可以取出如下:

<p>@ViewBag.book.Title</p>
<p>@(((HelloMVC.Models.KTBook)ViewData["ktb"]).Title)</p>

如果是ViewData["ktb"]的值,如前述提及會有型態的問題,因此第二行中必須經過轉型才能順利取出。

沒有留言: