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
- (二)Dynamic、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 的正確使用方式