ASP.NET MVC 系列4 - ViewData與TempData

過去在設計Web Forms的網頁程式時,後端程式碼常會使用伺服器控制項的元件來取得到資訊,並且將資料設定到伺服器控制項,然後ASP.NET會將Page底下的所有物件Render成Html程式碼,對於程式開發人員來說,也不需要太在意網頁與程式碼之間的互動是如何達成,設計起來跟設計Windows差不多,不過在MVC這邊可就沒這麼簡單了,因為不像Web Forms透過伺服器控制項來設定或式取得值,而是透過繼承Controller物件裡的ViewData以及TempData來和網頁進行資料存取。

之前對於ViewData與TempData的整理心得~~

  • ViewData

過去在設計Web Forms的網頁程式時,後端程式碼常會使用伺服器控制項的元件來取得到資訊,並且將資料設定到伺服器控制項,然後ASP.NET會將Page底下的所有物件Render成Html程式碼,對於程式開發人員來說,也不需要太在意網頁與程式碼之間的互動是如何達成,設計起來跟設計Windows差不多,不過在MVC這邊可就沒這麼簡單了,因為不像Web Forms透過伺服器控制項來設定或式取得值,而是透過繼承Controller物件裡的ViewData以及TempData來和網頁進行資料存取。

例如下面的程式碼是透過ViewData來將資料傳遞到前端的UI: 

//ViewDataController.cs 
namespace Test.Controllers 
{ 
    public class ViewDataController : Controller 
    { 
        public ActionResult ShowViewData() 
        { 
            ViewData["Message"] = "ViewData測試資料"; 
            return View(); 
        } 
    } 
}

 

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <%= ViewData["Message"]%>
</asp:Content>



在ShowViewData的Action方法中,透過Controller繼承來的ViewData物件來設定我們要顯示在前端的值,所以在前端網頁只要透過ViewData就可以取得在後端的資料。在上面的範例會在畫面上顯示「ViewData測試資料」。 ViewData主要目的是存放Controller的資料,當這些資料在產生(Render)Html原始碼時,可以從ViewData將資料取出,並設定到對應的Html Tag當中,但是ViewData只能在一個Action有效,所以它的生命周期只限於在一個頁面的請求,若是透過RedirectToAction等導頁到其他的Action處理時,ViewData的資料將會消失掉。來看看下面的程式碼:

//ViewDataController.cs
public class ViewDataController : Controller
{ 
    public ActionResult ShowViewData_1()
    {
        ViewData["Message"] = "ViewData測試資料";
        return RedirectToAction("ShowViewData1_Redirect");
    }

    public ActionResult ShowViewData1_Redirect()
    {
        //tMessage的值會是null
        string tMessage = ViewData["Message"] as string;  
        return View();
    }
}

所以當透過RedirectToAction將頁面導到ShowViewData1_Redirect時,ViewData[“Message”]的值就會變成null。

 

  • TempData

TempData基本上用法與ViewData幾乎是一模一樣,而且ViewData與TempData都是實做IDictionary介面而來的,但是差別在於TempData是將資料存放在 Session當中,而ViewData是存放在Controller的物件內。然而TempData的生命週期是在一個Request的範圍內,若是透過RedirectToAction導頁到不同的Action時,則可以取得到上一個Action所存放在TempData的資料。

 

//ViewDataController.cs
public class ViewDataController : Controller
{ 
    public ActionResult ShowTempData()
    {
        TempData["Message"] = "TempData測試資料";
        return View();
    }
    public ActionResult ShowTempData_Redirect()
    {
        //tMessage的值會是"TempData測試資料"
        string tMessage = TempData["Message"] as string;
        return View();
    }
}

<asp:content id="Content2" runat="server" contentplaceholderid="MainContent">
   <form method="get" action="\ViewData\ShowTempData_Redirect\">TempData的資料為:<!--TempData["Message"]--><br />
       <input type="submit" value="送出查詢" />
  </form>
</asp:content>

此範例與第一個範例相似,差別只在於這邊使用TempData來存放後端的資料,但是當我們透過submit按鈕將表單送到ShowTempData_Redirect的Action處理時,可以用相同的方式將資料取出,而不會是null。

小結:

雖然TempData的值是存放在Session當中,但是在MVC Framework當中只允許TempData導頁一次(透過RedirectToAction),當導頁後的Action取出TempData的資料時,會自動清空存放在TempData的資料(將Session清除),若是再透過RedirectToAction導頁到另外一個Action,此時的TempData取出的資料則會是null。

TempData的功能類似於ASP.NET的Session,但是差別在於存放的生命周期只允許導頁一次後取得資料,所以通常用在於暫存表單欄位驗證的錯誤訊息,或是可以當作成Html的隱藏欄位使用。