iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 5
1
Modern Web

ASP.NET MVC網頁程式介紹系列 第 5

[Day 05] ASP.NET MVC後端傳資料到前端介紹(一)

  • 分享至 

  • xImage
  •  

之前我們建了一個專案,但是完全沒有從後端帶任何資料到前端的頁面,那到底要如何將資料帶到前端呢?在MVC 中主要有兩種方式,一種是用ViewBag或ViewData等物件傳遞,另外一種方式是使用Model,那我們今天先看一下第一種方式。

首先這類的方式有三種物件

  • ViewData 物件:屬於 Dictionary Object ,能放入任何資料,使用 Key / Value 的概念存取。
  • ViewBag 物件:它和 ViewData 一樣,使用 Key / Value 存取,並能放入任何的資料,但不同的是,它能產生「動態屬性」。
  • TempData 物件:TempData 由字面上的意思看來,即告訴我們是「暫存」的資料,而暫存又是暫存多久?其實就是一次的請求,假定我們今天輸入網址 /Home/Index 而透過 Redirect 的方法轉向至 /Home/About ,若是用 ViewData 或 ViewBag 資料及會消失,但若透過 TempData 它能將資料傳遞至 /Home/About 供其使用,而最後返回頁面後 TempData 內的資料隨即消失,代表它的生命週期只有一次性,當使用一次我們就丟掉它。

之前有看過一篇文章,有提到ViewData的一些問題,還是建議使用ViewBag就好了,雖然我忘記是什麼問題,不過基本上我幾乎沒有使用過ViewData,所以這部分就跳過,我這次參考的文章也沒有提到ViewData的實作,在最後會附上這次的參考網頁,雖然大部分參考的內容都寫在上面了,下面的大多是自己的想法跟經驗,不過這一篇有提到一個很重要的觀念,記在下面:

ViewData和ViewBag內的資料都是透過Key/Value的方法來存取,但請注意在同個頁面中他們的key值還是不能重複,否則將會出現問題,後面的值會把前面的值蓋過去,導致讀出來的資料是有問題的。

網站上也有簡單的範例說明,有興趣的話可以去看。

我幾乎只會用到ViewBag來傳遞物件,不會用到ViewData及TempData,所以今天的例子也只用到ViewBag而已,ViewBag可以傳遞的物件很多,包括單一變數,一個Model,甚至Model的List,或者DataTable之類的物件都可以,我還沒有遇過ViewBag無法傳遞的物件。

在這個例子我們將之前的專案清空,以最原始的風貌來呈現,由於這30天主要在講後端跟JavaScript的部分,加上時間有限,因此沒有太多CSS的修飾,以功能為主的探討。

首先,Controller先將HomeController之外的Controller殺掉,再將HomeController除了index之外的都刪掉;Views的部分將Home跟Shared之外的資料夾刪掉,Home只留下index.cshtml一個檔案就好,其他資料夾不要亂動,刪錯了就準備重新新增一個專案了,index.cshtml的內容也清空,只留下上面@的區塊,並且加上 Layout = null; 表示不載入主版頁面,這樣執行出來就只會是一個空白的網頁,目前的程式碼如下。

@{
    ViewBag.Title = "Home Page";
    Layout = null;
}

ViewBag.Title目前是用不到了,一般是用來顯示標題用的,不過我也不特別拿掉它。

以下簡單用ViewBag來傳遞三種物件,Model的部分明天會提到,今天雖然有用到但不特別說明了,將程式碼跟網頁顯示出來的結果Show出來供大家參考。

以下是實作的部分:

Controllers/HomeController.cs的內容

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVCTest.Controllers
{
    public class HomeController : Controller
    {
        public class Student
        {
            public string id { get; set; }
            public string name { get; set; }
            public int score { get; set; }
            public Student()
            {
                id = string.Empty;
                name = string.Empty;
                score = 0;
            }
            public Student(string _id, string _name, int _score)
            {
                id = _id;
                name = _name;
                score = _score;
            }
            public override string ToString()
            {
                return $"學號:{id}, 姓名:{name}, 分數:{score}.";
            }
        }

        public ActionResult Index()
        {
            DateTime date = DateTime.Now;
            Student data = new Student();
            List<Student> list = new List<Student>();
            list.Add(new Student("1", "小明", 80));
            list.Add(new Student("2", "小華", 70));
            list.Add(new Student("3", "小英", 60));
            list.Add(new Student("4", "小李", 50));
            list.Add(new Student("5", "小張", 90));

            ViewBag.Date = date;
            ViewBag.Student = data;
            ViewBag.List = list;
            return View();
        }
    }
}

Views/Home/index.cshtml的內容

@{
    ViewBag.Title = "Home Page";
    Layout = null;

    var date = ViewBag.Date;
    var student = ViewBag.Student;
    var list = ViewBag.List;
}

<style>
    div
    {
        margin-bottom: 10px;
    }
</style>

<div>
    現在時間: @date.ToString("yyyy/MM/dd HH:mm:ss") 
</div>

<div>
    學生成績: @student.ToString()
</div>

<div>
    學生成績列表:
</div>
@for (int i = 0; i < list.Count; i++)
{
    <div>
        @list[i].ToString()
    </div>
}

網頁顯示的畫面

https://ithelp.ithome.com.tw/upload/images/20171214/201056943CFEXfjMEX.jpg

今天先寫到這邊,
明天主要講解今天的程式內容。

附上今天的參考資料:
[ASP.NET MVC] ASP.NET MVC 傳遞資料容器(一) - ViewData vs ViewBag

--
小弟不才,
如果有謬誤或是要補充的,
都歡迎一起來討論!


上一篇
[Day 04] 我的第一個MVC專案(二)
下一篇
[Day 06] ASP.NET MVC後端傳資料到前端介紹(二)
系列文
ASP.NET MVC網頁程式介紹30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
4
石頭
iT邦高手 1 級 ‧ 2017-12-15 09:17:02

補充一下:

  1. ViewBag 雖然返回值是dymanic 但其實也是ViewData
  2. 我們在View上使用的 @Model 其實是 ViewData.Model
  3. TempData 可以跨請求原因是把資料存在Session中,有興趣的可以去MVC原始碼看看SessionStateTempDataProvider 這個類別
小魚 iT邦大師 1 級 ‧ 2017-12-15 22:36:11 檢舉

感謝補充,我再研究看看
/images/emoticon/emoticon33.gif

0
tommy_lu1
iT邦新手 5 級 ‧ 2018-01-25 01:04:46

為什麼我套用你的程式碼,中文字會產生亂碼呢?

小魚 iT邦大師 1 級 ‧ 2018-01-25 11:58:42 檢舉

你是用Mac的吧,
Mac我就不知道了,
不過亂碼這種東西跟編碼有關,
你要去看哪裡的編碼出了問題,
我們現在通常用的都是UTF-8.

0
allenchen130
iT邦新手 5 級 ‧ 2019-07-18 09:58:12

https://ithelp.ithome.com.tw/upload/images/20190718/20119141uKrcBakYSQ.png
想請問:return有辦法一次回傳多個值嗎?

小魚 iT邦大師 1 級 ‧ 2019-07-18 10:18:21 檢舉

$是 VS 2015 之後才可以用的,
你用的應該是舊的版本,
如果沒有特別原因一定要使用舊版本的話,
我蠻推薦使用VS 2015的,
倒是可以以這個版本為主作開發.

return 基本上只能回傳一個object,
如果要回傳多個值,
可以自己寫一個類別(class)來做回傳.

不過還有其他的方式,
如 ref 跟 out,
這部分如果不清楚可以Google一下.

好的!我後來將return全部轉為string並集中到一個變數之中,就成功回傳了,謝謝您!

我要留言

立即登入留言