[ASP.NET][MVC]Multiple Models(一)ViewBag、ViewData、TempData

Controller Action要將資料傳遞到前端顯示有很多種方式,常透過View Result下的ViewBag、ViewData、Model及Session中的Temp Data。

如果是資料模型通常就直接用Model或View Model再包裹;簡單的資料結構(訊息字串..)則可以用前面幾種;但使用者的頁面總是希望很豐富,要呈現多個資料表Model結構就要轉一下,最近要選擇MVC撰寫方式作為範本,來筆記順便比較幾種作法。

 

 

和同學討論後,同時找到網路上幾種解答:

  • View Bag
  • View Data
  • Temp Data
  • ExpandoObject
  • Tuple 
  • View Model
  • Partial View
  • Ajax 

分成三部分完成筆記:

 

今天就從(一)ViewBag、ViewData及TempData開始! 

  • ViewBag是ASP.NET MVC後期發展出來的,使用機會很多,是一種動態運算式(Dynamic型別),只能單向傳遞,生命週期也只有單一Request;撰寫程式時沒有intellisense,也沒辦法在編譯期找出錯誤
  • ViewData則是ASP.NET MVC早期的產物,是一種Key/Value Pair的型別,ViewBag具有的缺點都有,還多了一個使用前必須轉換的步驟
  • TempData也是Key/Value Pair的型別,所有ViewData的缺點都有,不過TempData可以跨Controller、跨View,但儲存在Session

 

先前上課整理的筆記:

*哈!感謝Demo本人提供指正!

 

1.首先建立一個ASP.NET Web應用程式

範本選Empty > 資料夾及核心參考選MVC > 確定

2.建立資料類別及範例資料

昨天跑完巴西站,今年就剩下阿布達比站 (Abu Dhabi) 的閉幕站了,這次就用F1主要車隊和車手作為測試資料!

 

F1Team.cs 建立車隊資料

namespace MultiModel.Models
{
    public class F1Team
    {
        public string Name { get; set; }
        public int ChampionshipTitles { get; set; }
        public String Country { get; set; }
    }
}

F1Driver.cs 建立車手資料

namespace MultiModel.Models
{
    public class F1Driver
    {
        public string Name { get; set; }
        public string Team { get; set; }
        public string Country { get; set; }
        public int WDCs { get; set; }
    }
}

Repository.cs 資料倉庫

using System.Collections.Generic;
namespace MultiModel.Models
{
    public class Repository
    {
        public List<F1Team> GetTeams()
        {
            return new List<F1Team> {
                    new F1Team () {  Name = "Mercedes AMG", ChampionshipTitles = 2, Country= "Germany"},
                    new F1Team () {  Name = "Red Bull Racing", ChampionshipTitles = 4, Country= "Austria"},
                    new F1Team () {  Name = "McLaren", ChampionshipTitles = 8, Country= "United Kingdom"},
                    new F1Team () {  Name = "Ferrari", ChampionshipTitles = 16  , Country = "Italy" }};
        }

        public List<F1Driver> GetDrivers()
        {
            return new List<F1Driver> {
                    new F1Driver () {  Name = "Lewis Hamilton", Team = "Mercedes AMG", WDCs = 3, Country= "United Kingdom"},
                    new F1Driver () {  Name = "Nico Rosberg", Team = "Mercedes AMG",WDCs = 0, Country= "Germany"},
                    new F1Driver () {  Name = "Daniel Ricciardo",Team = "Red Bull Racing", WDCs = 0, Country= "Australia"},
                    new F1Driver () {  Name = "Max Verstappen",Team = "Red Bull Racing", WDCs = 0, Country= "Netherlands"},
                    new F1Driver () {  Name = "Sebastian Vettel",Team = "Ferrari", WDCs = 4, Country= "Germany"},
                    new F1Driver () {  Name = "Kimi Räikkönen",Team = "Ferrari", WDCs = 1, Country= "Finland"},
                    new F1Driver () {  Name = "Fernando Alonso",Team = "McLaren", WDCs = 2, Country= "Spain"},
                    new F1Driver () {  Name = "Jenson Button", Team = "McLaren",WDCs = 1  , Country = "United Kingdom" }};
        }
    }
}

 

3.新增控制器 F1Controller.cs

 

View Bag

打開F1Controller.cst程式,編寫以下程式碼

依序從資料倉庫取出F1車隊和車手資料!

using MultiModel.Models;
using System.Web.Mvc;

namespace MultiModel.Controllers
{
    public class F1Controller : Controller
    {
        // GET: F1
        Repository repository = new Repository();
        public ActionResult ViewBagIndex()
        {
            ViewBag.Teams = repository.GetTeams();
            ViewBag.Drivers = repository.GetDrivers();
            return View();
        }
    }
}

4.建立檢視

都用View Bag來接,用View Engine(Razor) foreach來顯示。

html>
<body>
    <h2>ViewBag</h2>
    <h3>車隊</h3>
    <table id="Teamlist" class="table table-hover">
        <thead>
            <tr>
                <td>車隊名稱</td>
                <td>年度世界冠軍次數</td>
                <td>國籍</td>
            </tr>
        </thead>
        <tbody>
            @foreach (var items in ViewBag.Teams)
            {
                <tr>
                    <td>@items.Name</td>
                    <td>@items.ChampionshipTitles</td>
                    <td>@items.Country</td>
                </tr>
            }
        </tbody>
    </table>
    <h3>車手</h3>
    <table id="Driverlist" class="table table-hover">
        <thead>
            <tr>
                <td>車手姓名</td>
                <td>車隊</td>
                <td>國籍</td>
                <td>年度世界冠軍次數</td>
            </tr>
        </thead>
        <tbody>
            @foreach (var items in ViewBag.Drivers)
            {
                <tr>
                    <td>@items.Name</td>
                    <td>@items.Team</td>
                    <td>@items.Country</td>
                    <td>@items.WDCs</td>
                </tr>
            }
        </tbody>
    </table>

</body>
</html>

 

看看成果!

 

View Data

key/value 型態

1.打開F1Controller.cst程式,新增以下Action程式碼

public ActionResult ViewDataIndex()
{
    ViewData["Teams"] = repository.GetTeams();
    ViewData["Drivers"] = repository.GetDrivers();
    return View();
}

 

2.新增檢視ViewDataIndex.cshtml

編寫view程式碼

<html>
<body>
    <h2>ViewData</h2>
    <h3>車隊</h3>
    <table id="Teamlist" class="table table-hover">
        <thead>
            <tr>
                <td>車隊名稱</td>
                <td>年度世界冠軍次數</td>
                <td>國籍</td>
            </tr>
        </thead>
        <tbody>
            @foreach (var items in ViewData["Teams"] as List<MultiModel.Models.F1Team>)
            {
                <tr>
                    <td>@items.Name</td>
                    <td>@items.ChampionshipTitles</td>
                    <td>@items.Country</td>
                </tr>
            }
        </tbody>
    </table>
    <h3>車手</h3>
    <table id="Driverlist" class="table table-hover">
        <thead>
            <tr>
                <td>車手姓名</td>
                <td>車隊</td>
                <td>國籍</td>
                <td>年度世界冠軍次數</td>
            </tr>
        </thead>
        <tbody>
          @foreach (var items in ViewData["Drivers"] as List<MultiModel.Models.F1Driver>)
            {
                <tr>
                    <td>@items.Name</td>
                    <td>@items.Team</td>
                    <td>@items.Country</td>
                    <td>@items.WDCs</td>
                </tr>
            }
        </tbody>
    </table>
</body>
</html>

 

來測試看看!

 

TempData

key/value 型態

1.打開F1Controller.cst程式,新增以下Action程式碼

public ActionResult TempDataIndex()
{
    TempData["Teams"] = repository.GetTeams();
    TempData["Drivers"] = repository.GetDrivers();
    return View();
}

 

2.新增檢視TempDataIndex.cshtml

編寫view程式碼

<html>
<body>
    <h2>TempData</h2>
    <h3>車隊</h3>
    <table id="Teamlist" class="table table-hover">
        <thead>
            <tr>
                <td>車隊名稱</td>
                <td>年度世界冠軍次數</td>
                <td>國籍</td>
            </tr>
        </thead>
        <tbody>
            @foreach (var items in TempData["Teams"] as List<MultiModel.Models.F1Team>)
            {
                <tr>
                    <td>@items.Name</td>
                    <td>@items.ChampionshipTitles</td>
                    <td>@items.Country</td>
                </tr>
            }
        </tbody>
    </table>
    <h3>車手</h3>
    <table id="Driverlist" class="table table-hover">
        <thead>
            <tr>
                <td>車手姓名</td>
                <td>車隊</td>
                <td>國籍</td>
                <td>年度世界冠軍次數</td>
            </tr>
        </thead>
        <tbody>
            @foreach (var items in TempData["Drivers"] as List<MultiModel.Models.F1Driver>)
            {
                <tr>
                    <td>@items.Name</td>
                    <td>@items.Team</td>
                    <td>@items.Country</td>
                    <td>@items.WDCs</td>
                </tr>
            }
        </tbody>
    </table>
</body>
</html>

來測試看看!

 

小結就用前幾天看到Demo大分享的ASP.NET MVC Multiple ViewModel 的正確使用方式

這篇的作法相較二三篇的作法不太便利喔!就當是一種對照組。

 

 

參考:

Multiple Models in Single View in MVC

ASP.NET MVC Multiple ViewModel 的正確使用方式

Formula 1