首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET MVC 中 TempData、ViewData、ViewBag 三大資料傳遞機制完整比較

     編輯:關於ASP.NET

ASP.NET MVC 中 TempData、ViewData、ViewBag 三大資料傳遞機制完整比較

ASP.NET MVC 控制器向視圖傳遞資料有三種主要機制:ViewData、ViewBag、TempData。它們生命週期、型別安全性、適用場景各異,正確選擇至關重要。

核心差異速查表

特性ViewDataViewBagTempData
型別ViewDataDictionary (字典)動態物件 (DynamicObject)TempDataDictionary (字典)
語法ViewData["key"] = valViewBag.Key = valTempData["key"] = val
型別安全無 (需轉型)無 (動態解析)無 (需轉型)
生命週期當前請求 (Controller → View)當前請求 (Controller → View)當前請求 + 下一個請求 (重導向場景)
儲存機制Session (預設)Session (預設)Session (預設)
自動清除視圖渲染後視圖渲染後讀取後 (或 Keep() 保留)
IntelliSense無有 (動態屬性)無

ViewData:字典基礎機制


// Controller
public ActionResult Index() {
    ViewData["Message"] = "Hello World!";
    ViewData["UserCount"] = 42;
    return View();
}

// View (Razor)
<h1>@ViewData["Message"]</h1>
<p>用戶數: @ViewData["UserCount"]</p>
  • 本質是 Dictionary<string, object>,需字串鍵值存取。
  • 視圖中取值需轉型:(int)ViewData["UserCount"]。
  • 鍵名拼寫錯誤執行時才發現,無編譯期檢查。

ViewBag:動態包裝器 (C# 4.0+)


// Controller
public ActionResult Index() {
    ViewBag.Message = "Hello World!";
    ViewBag.UserCount = 42;
    ViewBag.User = new { Name = "Tom", Role = "Admin" }; // 匿名型別
    return View();
}

// View
<h1>@ViewBag.Message</h1>
<p>@ViewBag.User.Name</p>
  • 內部封裝 ViewData,透過 DynamicObject 提供屬性語法。
  • 語法更簡潔,支援巢狀動態屬性。
  • 同樣無編譯期型別檢查,拼寫錯誤執行時拋出 RuntimeBinderException。

TempData:跨請求資料傳遞 (PRG 模式核心)


// Controller - 動作 A (POST 處理)
[HttpPost]
public ActionResult Create(FormModel model) {
    if (ModelState.IsValid) {
        _service.Save(model);
        TempData["SuccessMessage"] = "資料已儲存!"; // 存入 TempData
        return RedirectToAction("Index"); // PRG: 重導向至 Index
    }
    return View(model);
}

// Controller - 動作 B (GET 顯示)
public ActionResult Index() {
    // TempData 自動保留到此請求,讀取後標記刪除
    ViewBag.Message = TempData["SuccessMessage"]; // 取出傳給 ViewBag
    return View();
}

// View (Index)
@if (ViewBag.Message != null) {
    <div class="alert alert-success">@ViewBag.Message</div>
}
  • 專為 Post-Redirect-Get (PRG) 模式設計:POST 動作存資料 → 重導向 → GET 動作取資料顯示。
  • 預設讀取即刪除:TempData["key"] 存取後標記移除,下一請求不可用。
  • TempData.Keep("key") 或 TempData.Keep() 保留到再下一請求。
  • TempData.Peek("key") 僅讀取不標記刪除。

實戰選擇指南

場景推薦機制理由
Controller → View 一般資料ViewModel (強型別)編譯期檢查、IntelliSense、重構安全、關注點分離
少量臨時資料、快速原型ViewBag語法簡潔、動態彈性
需轉型、字典語意明確ViewData明確字串鍵、相容舊代碼
重導向後顯示成功/錯誤訊息TempData跨請求生命週期、自動清除符合 PRG
多步驟精靈、跨多請求暫存TempData + Keep()手動控制保留輪數

最佳實務:強型別 ViewModel 為主


// ViewModel
public class ProductViewModel {
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string SuccessMessage { get; set; } // 包含 TempData 內容
}

// Controller
public ActionResult Index() {
    var vm = new ProductViewModel {
        SuccessMessage = TempData["SuccessMessage"]?.ToString()
    };
    return View(vm);
}

// View (@model ProductViewModel)
@if (!string.IsNullOrEmpty(Model.SuccessMessage)) {
    <div class="alert-success">@Model.SuccessMessage</div>
}
  • ViewModel 模式 解決所有三者的型別不安全、重構脆弱、測試困難問題。
  • TempData 僅用於跨請求傳遞原始資料,控制器讀取後立即映射到 ViewModel。
  • 視圖完全強型別,享受完整工具支援。

Session 儲存提供者影響

  • 預設使用 InProc Session,單機部署正常。
  • Web Farm/雲端部署需切換 StateServer、SQLServer、Redis (ASP.NET Core IDistributedCache),確保 TempData/ViewData 跨實例共享。
  • 無 Session 情境 (Web API、SignalR) 不應依賴此三者。

總結

  • ViewData/ViewBag:單一請求 Controller→View,語法偏好不同,均不建議大量使用。
  • TempData:PRG 模式專用,跨重導向請求傳遞暫時資料。
  • 黃金法則:強型別 ViewModel 為主,三者僅作為輔助/遷移過渡方案。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved