3-7.ASP.NET Core MVC 入門教學 - 使用TempData傳遞資料

ASP.NET Core MVC 入門教學

上一節我們學到了用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"]

那畫面沒有意外就是如下

用法可以說是跟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是原來的首頁,沒有多出任何值

接著再去https://localhost:7062/pay,設定一下TempData,因為我們剛剛已經把@TempData["title"]拿掉,所以應該回是一片空白

接著再回到https://localhost:7062,可以發現,我們設定的值出現了

但重新整理之後會發現,值又消失了,還記得開頭講的嗎,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

 

範例檔:下載




Copyright © 凱哥寫程式 2022 | Powered by TalllKai ❤