iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 9
0
Modern Web

從Asp.Net MVC5的起跑點認識現代網站系列 第 9

Day9_Controller傳資料給View的方法(ViewData、ViewBag、TempData)

我們一開始最普遍帶資料給View的方式是透過return View(),而我們今天要來測試三種傳值得方法。

 public ActionResult Index()
        {
            private ProductEntities db = new ProductEntities();
            return View(db.Products.ToList()); 
        }

ViewData

  • 引用System.Web.Mvc.ViewDataDictionary,屬於Dictionary Object,能放Property或是一個Model的IEnumerable,使用Key/Value的概念存取。
  • 生命週期為一個頁面

ViewBag

  • 引用System.Web.Mvc.ControllerBase.ViewBag,與ViewData相似,不同在於型別是dynamic object(動態物件),使用上較方便不用特意轉型,但缺點是由於動態物件的關係速度稍慢。

TempData

  • 引用System.Web.Mvc.TempDataDictionary ,屬於key-value dictionary
  • 生命週期可以跨一個request,意旨我可以將值傳到另一個Action使用,使用一次後就會消失

測試ViewData、ViewBag

我們透過三種方式將產品的資料傳到View做使用。

public ActionResult Index()
        {
            ViewData["Name"] = db.Products.ToList();
            ViewBag.products = db.Products.ToList();
            return View(db.Products.ToList());
        }

View頁面

  • 一般用法,透過return View(data)
    http://ithelp.ithome.com.tw/upload/images/20161224/20103808fnHK6zkWsm.jpg
    在View中引入@model IEnumerable<Product>的強型別方式綁定欄位資料。

  • 透過ViewData
    http://ithelp.ithome.com.tw/upload/images/20161224/20103808TACrCfMrK5.jpg
    ViewData屬於object型別,因此我們必須透過轉型成強型別的方式,ViewData["Name"] as IEnumerable<Product>,才能正確抓取資料。
    假如沒加的錯誤訊息
    http://ithelp.ithome.com.tw/upload/images/20161224/20103808BnZsM09ZHZ.jpg

  • 透過ViewBag
    http://ithelp.ithome.com.tw/upload/images/20161224/20103808XN9haGD58R.jpg
    ViewBag屬於動態物件,所以可以直接抓取值,雖然程式碼很短,但屬於弱型別,如果條件太複雜的情況下,並不好偵錯。

TempData

TempData可以跨一個Request讀取,這是ViewData、ViewBag所沒有的特性,那是因為TempData本身屬於Session,而他在讀取一次之後就會消失,比起直接使用 Session 對伺服器的負擔來的輕很多,如果目的希望暫存某筆資料而當使用者在下次存取後就丟棄它,這時就可以考慮用 TempData 來存放了。

public ActionResult Index()
        {
            TempData["Time"] = DateTime.UtcNow.AddHours(8);
            return View(db.Products.ToList());
        }

        // GET: Products/Details/5
        public ActionResult Details(int? id)
        {
            if (TempData["Time"]!= null)
            {
                DateTime time = (DateTime)TempData["Time"];
                ViewBag.time = time;
            }          
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Product product = db.Products.Find(id);
            if (product == null)
            {
                return HttpNotFound();
            }
            return View(product);
        }

上述的Code是當進入Index時,紀錄當下時間,再到Details頁面的時候顯示出進入網站的時間。
http://ithelp.ithome.com.tw/upload/images/20161224/20103808W563hFIpBH.jpg

結論

ViewData、ViewBag、TempData不適合用來傳遞大量的資料,因為在設計上他們不屬於強型別,這在程式偵錯上會比較困難,如果資料太複雜ViewModel反而會更適合,也相對容易維護,ViewData、ViewBag使用時機上,在傳遞小量資料時,他們就相對很方便,例如要傳遞一個DropdownList到View使用等,而TempData則是資料要從一個action傳遞至另一個Action時很適合,例如:error訊息等等。


上一篇
Day8_Model驗證欄位與自訂驗證
下一篇
Day10_ActionFilter
系列文
從Asp.Net MVC5的起跑點認識現代網站30

尚未有邦友留言

立即登入留言