上一節我們學到了用ViewData或ViewBag簡單來傳遞資料
那這節再介紹一個差不多用法的TempData
而兩者的差別在於,ViewData或ViewBag生命週期只有這次的Request
但TempData可以再下次讀取前值都還存在,也就是可以跨Request、跨Controller傳遞資料
我們先來看看基本用法
PayController.cs
namespace WebApplication1.Controllers
{
public class PayController : Controller
{
public IActionResult Index()
{
TempData["title"]= "這是用TempData傳遞的資料。";
return View();
}
}
}
Views/Pay/Index.cshtml
@TempData["title"]
那畫面沒有意外就是如下
![](/uploadImg/image_436.png)
用法可以說是跟ViewData一樣,不過同一個Request看不出效果,所以我們把@TempData["title"]放在HomeController的index上試試
當然記得要拿掉Views/Pay/Index.cshtml裡的@TempData["title"]
然後在Views/Home/Index.cshtml上加上@TempData["title"]
@{
ViewData["Title"] = "Home Page";
}
@TempData["title"]
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
接著我們先去https://localhost:7062是原來的首頁,沒有多出任何值
![](/uploadImg/image_437.png)
接著再去https://localhost:7062/pay,設定一下TempData,因為我們剛剛已經把@TempData["title"]拿掉,所以應該回是一片空白
![](/uploadImg/image_438.png)
接著再回到https://localhost:7062,可以發現,我們設定的值出現了
![](/uploadImg/image_439.png)
但重新整理之後會發現,值又消失了,還記得開頭講的嗎,TempData的值在預設上會在某次有Requset讀取之後就會消失
既然特別有講預設,代表可以改變這個特性,如果我們想要在讀取後值還是保留著我們就要加一個指令
這是HomeController.cs的Index
public IActionResult Index()
{
TempData.Keep("title");
return View();
}
這樣我們在pay設定TempData
後,回到Home重新不管整理多少次都會在
但有一點要注意,這個保留是只保留這次Requset讀取後還會在,不是永久保留,影片會有示範
另外我有看到有人拿TempData當已登入的身分認證用,這種作法在20年前WebForm時代很常見,是用Session來實現
但TempData的機制很明顯就不適合拿來這麼做,因為身分驗證基本是要長時間存在的
不太可能會用一個讀取就會消失的功能拿來做這件事
這個例子很好的說明,當我們用任何東西,不僅要能運作,還是要多了解一下觀念,不然會有很多東西誤用了,造成一些不太好的寫法
所以我這邊也簡單來舉個例子,而TempData跟ViewData或ViewBag一樣
應該是拿來傳遞不這麼重要而且直覺的東西,像身分認證這種東西就太重要了,明顯不適合
做個簡單的例子,今天我買完東西要付款,可以用ATM跟Line Pay付款
分別有兩個方法在處理不同的付款,最後付完款後導向付款成功頁面,並秀出你用什麼完成付款
PayController.cs
namespace WebApplication1.Controllers
{
public class PayController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult ATM()
{
//一些付款的程序
//成功後留下成功字樣
TempData["title"] = "使用ATM完成付款";
return RedirectToAction("PayOK");
}
public IActionResult LinePay()
{
//一些付款的程序
//成功後留下成功字樣
TempData["title"] = "使用Line Pay完成付款。";
return RedirectToAction("PayOK");
}
public IActionResult PayOK()
{
if (TempData["title"] == null)
{
return RedirectToAction("Index");
}
return View();
}
}
}
Views/Pay/Index.cshtml
<a href="~/pay/ATM">使用ATM完成付款</a>
<br/>
<a href="~/pay/LinePay">使用Line Pay完成付款。</a>
這邊做兩個連結,假裝一下在付款
Views/Pay/PayOK.cshtml
@TempData["title"]
<br/>
<a href="~/pay">Pay</a>
這邊秀出你用什麼方式付款
而剛剛上面在 PayOK()有判斷如果@TempData["title"]
是空的,就踢回付款頁面
剛好很適合用TempData的特性來實現,當TempData沒有值就進來這頁,代表是非法或誤進,所以我們把他踢回首頁
如果有值就代表剛完成付款,所以秀出付款成功頁面
因此我們重新整理PayOK這頁後,就會被踢回付款頁面
這個例子雖然簡單,但卻很好的利用了TempData的特性,來實現這個運作流程
可以看到在這個例子用TempData扮演的角色就是一個單純的提醒,這類簡單的事情就適合用TempData
範例檔:下載