dotNET5的MVC頁(yè)面?zhèn)髦捣绞娇偨Y(jié)

本文大致講解mvc前后端的傳值方式,包括control向view啃憎、view向control先朦、以及action向action。

一.經(jīng)典回顧

我們回顧下在ASP.NET WebForms中,頁(yè)面之間最常用的傳值方式蹲诀,有以下幾種:

  • a). QueryString(也叫URL傳值)
  • b). Session
  • c). Cookie
  • d). Application
  • e). Server.Transfer

這里不再講述這幾種傳值方式的用法和利弊斑粱,在本章后面將用MVC的傳值方式與之對(duì)比,并展開(kāi)一些探討脯爪。(webform傳值請(qǐng)看其他章節(jié))

二则北、Controller向View傳值

可以通過(guò)viewbag、viewdata痕慢、TempData尚揣、model。

1. ViewBag

1.png

用法:
在Controller中書(shū)寫(xiě)

ViewBag.Test123 = "Hello World.";

前臺(tái)接收

@ViewBag.Test123

說(shuō)明: ViewBag是dynamic動(dòng)態(tài)類(lèi)型掖举,上面例子中的key => Test123可以指定任何類(lèi)型

2. ViewData

2.png

用法:

在Controller中書(shū)寫(xiě)

ViewData["Test123"] = "Hello World. This is ViewData";

前臺(tái)接收

@ViewData["Test123"]

說(shuō)明:ViewData是字典類(lèi)型快骗,繼承自IDictionary<string,object>接口

3. TempData

3.png

用法:

在Controller中書(shū)寫(xiě)

TempData["tmpData"] = "I am TempData...";

前臺(tái)接收

@TempData["tmpData"]

說(shuō)明:TempData也是字典類(lèi)型,繼承自IDictionary<string,object>接口

4. Model

這是初學(xué)者最常使用的傳值方式塔次。在上一篇文章中方篮, 我們?cè)赗azor視圖的頁(yè)面代碼中有這樣一句:

@model IEnumerable<MVC5Demo.Models.UserInfoViewModel>

然后我們的信息列表是這樣:

<tbody>
    @foreach (var item in Model) { 
    <tr>
        <td>@Html.DisplayFor(p => item.UserName)</td>
        <td>@(item.Sex == 0 ? "女" : "男")</td>
        <td>@Html.DisplayFor(p => item.Age)</td>
        <td>@Html.DisplayFor(p => item.Dept)</td>
        <td>@Html.ActionLink("編輯", "Edit", "UserInfo", new { id=item.UserID.ToString() },null) @Html.ActionLink("刪除", "Delete", "UserInfo", new { id = item.UserID.ToString() }, new { onclick="return confirm('確認(rèn)刪除"+item.UserName+"的記錄?');" })</td>
    </tr>
    }
</tbody>

如代碼所示励负,因?yàn)槲覀兊腗odel是一個(gè)泛型集合藕溅,這里就可以很方便的取出集合中的數(shù)據(jù)。

在后臺(tái)Controller中继榆,是怎么書(shū)寫(xiě)的呢巾表?

public ActionResult Index()
        {
            return View("UserInfo", GetTestData());//GetTestData()返回泛型集合
        }

如代碼所示,只需返回視圖時(shí)略吨,同時(shí)指定視圖的數(shù)據(jù)對(duì)象集币。

三、View向Controller傳值

1. 使用Html.BeginForm(...)方法提交表單

@using(Html.BeginForm("actionName","controllerName"))
    {
        <div>表單內(nèi)容</div>
        <div>...</div>
        <input type="submit" value="提交表單" />
    }

說(shuō)明:將 <form> 開(kāi)始標(biāo)記寫(xiě)入響應(yīng)翠忠。在用戶(hù)提交窗體時(shí)惠猿,將由某個(gè)操作方法(指定Controller的某個(gè)Action)處理該請(qǐng)求。

(使用using關(guān)閉form负间,下面不再說(shuō)明偶妖。)

2. 使用Html.BeginRouteForm(...)方法提交表單

@Html.BeginRouteForm("路由名稱(chēng)", new { controller = "userinfo", action="save", userID = Model.UserID, userName = Model.UserName }, FormMethod.Post)
    {
        <div>表單內(nèi)容</div>
        <div>...</div>
        <input type="submit" value="提交表單" />
    }

說(shuō)明:同Html.BeginForm(),但使用路由方式提交表單,同時(shí)參數(shù)也不同政溃。

3. 傳統(tǒng)Form表單的Action屬性提交

<form id="postForm" action="@Url.Action("Save")" method="post">
            <div>表單內(nèi)容</div>
            <div>...</div>
            <input type="submit" value="提交表單" />
    </form>

說(shuō)明:使用傳統(tǒng)html form原生標(biāo)記趾访。

4. 使用Ajax方式提交表單, Ajax.BeginForm(...)

@Ajax.BeginForm("actionName", new AjaxOptions { Url="",OnSuccess="",HttpMethod="get" })
    {
        <div>表單內(nèi)容</div>
        <div>...</div>
        <input type="submit" value="提交表單" />
    }

說(shuō)明:使用異步方式提交form表單。

5. Jquery和Ajax提交表單

省略... 不在文章討論范圍董虱。

6. 表單參數(shù)傳遞

6.1 全參數(shù)傳遞

[HttpPost]
public ActionResult Save(string username,int sex,int age,string dept)

說(shuō)明:html標(biāo)簽name和參數(shù)名需相同扼鞋。

6.2 實(shí)體傳參

[HttpPost]
public ActionResult Save(UserInfoViewModel item)

說(shuō)明:頁(yè)面使用@model綁定類(lèi)型

6.3 表單集合傳參

[HttpPost]
public ActionResult Save(FormCollection fc)

說(shuō)明:需解析FormCollection,如:

UserInfoViewModel userInfo = new UserInfoViewModel();
TryUpdateModel<UserInfoViewModel>(userInfo, fc);

6.4 傳統(tǒng)方式

使用HttpContext,在MVC中我們同樣可以使用以下對(duì)象:

Application,Server,Session,Request,Response,Cache ...

四申鱼、Controller向Controller傳值(Action之間傳值)

1. RedirectToAction

1.1 傳遞實(shí)體對(duì)象

public ActionResult Index()
        {
            return RedirectToAction("Index", "Home", new UserInfoViewModel { UserID = Guid.NewGuid(), UserName = "zhangsan", Sex = 1, Age = 20, Dept = "hr" });
        }

說(shuō)明:在UserInfoController中,在頁(yè)面加載時(shí)云头,新建一個(gè)實(shí)體類(lèi)型捐友,并跳轉(zhuǎn)至首頁(yè)。

接收:

public class HomeController : Controller
    {
        public ActionResult Index(UserInfoViewModel model)
        {
            //處理model的值
            //...

1.2 傳遞普通參數(shù)

public ActionResult Index()
        {
            return RedirectToAction("Index", "Home", new { UserID = Guid.NewGuid(), UserName = "zhangsan"});
        }

接收:

public class HomeController : Controller
    {
        public ActionResult Index(string userID,string userName)
        {
            //處理userID, userName的值
            //...
  1. TempData
TempData["userName"] = "zhangsan";
            return RedirectToAction("Index2");

在Index2中接收:

string userName = TempData["userName"].ToString();

說(shuō)明:TempData可以在同Controller中不同Action之間傳遞溃槐,并且具有‘一次訪問(wèn)’的特質(zhì)匣砖。使用時(shí)要特別注意。

五昏滴、與WebForms傳值的對(duì)比

  1. 后臺(tái)不能通過(guò)非提交方式獲取某個(gè)頁(yè)面元素的值猴鲫,因?yàn)闆](méi)有‘服務(wù)器控件’;MVC使用原生Http谣殊,是【無(wú)狀態(tài)】的拂共。

  2. 不能使用(也沒(méi)有)ViewState。

  3. 使用特有的機(jī)制傳值(ViewData姻几,ViewBag...等等)宜狐。

六、MVC 向頁(yè)面?zhèn)髦捣绞娇偨Y(jié)

總結(jié)發(fā)現(xiàn)ASP.NET MVC中Controller向View傳值的方式共有6種蛇捌,分別是:

  • ViewBag
  • ViewData
  • TempData
  • 向普通View頁(yè)面?zhèn)饕粋€(gè)Model對(duì)象
  • 向強(qiáng)類(lèi)型頁(yè)面?zhèn)鱾饕粋€(gè)Model對(duì)象
  • 用一個(gè)ViewModel對(duì)象解決所有問(wèn)題

首先我們需要明確的是我們從controller向view傳值的時(shí)候抚恒,這些方式分別處于什么樣的地位:

我們一般會(huì)向頁(yè)面?zhèn)鬟f一個(gè)主要的類(lèi)型的數(shù)據(jù),一般是情況下是一個(gè)List<Model>豁陆,如果只有這個(gè),很好辦吵护,一個(gè)model對(duì)象就解決了盒音,但是往往除此之外還會(huì)有一些額外的零散的數(shù)據(jù)需要傳遞,比如分頁(yè)的pageIndex馅而,或者pageCount等等祥诽,這樣的數(shù)據(jù)用原有的model就無(wú)能為力了,這時(shí)候瓮恭,我們就可以用ViewBag雄坪、ViewData、TempData來(lái)傳遞這些額外的數(shù)據(jù)屯蹦。

視圖數(shù)據(jù)可以通過(guò)ViewBag屬性訪問(wèn)维哈,它主要是為了從Controller到view進(jìn)行傳值用的,類(lèi)似有所使用的ViewData[] 字典類(lèi)登澜。對(duì)于ViewBag是如此的強(qiáng)大阔挠,意味著你能動(dòng)態(tài)的set/get 值,增加任何數(shù)量的的額外字段而不需要強(qiáng)類(lèi)型的檢測(cè)脑蠕。如:

control控制器

public 
ActionResult Index()

{

List<string>
 colors = new 
List<string>();

colors.Add("red");

colors.Add("green");

colors.Add("blue");




ViewData["listColors"]
 = colors;

ViewData["dateNow"]
 = DateTime.Now;

ViewData["name"]
 = "Hajan";

ViewData["age"]
 = 25;



return 
View();

control 控制器

public 
ActionResult Index()

{

List<string>
 colors = new 
List<string>();

colors.Add("red");

colors.Add("green");

colors.Add("blue");



ViewBag.ListColors = colors;
//colors
 is List

ViewBag.DateNow
 = DateTime.Now;

ViewBag.Name
 = "Hajan";

ViewBag.Age
 = 25;

return 
View(); 

}

你和上面的對(duì)比 你看見(jiàn)了不同嗎购撼?

View
對(duì)應(yīng)前臺(tái)視圖:

1.使用ViewData

<p>
My name is <b>@ViewData["name"] </b>,
<b>
<br />
I like the following colors:
</p>
<ul id="colors">
@foreach (var color in ViewData["listColors"] as List<string>)
{
<li><font color="@color">@color </font></li>
}
</ul>
<p>
@ViewData["dateNow"]
</p>

2.使用ViewBag

<p>
My name is < b>@ViewBag.Name</b>, <b>@ViewBag.Age</b> years old.
<br />
I like the following colors:
</p>
<ul id="colors">
@foreach (var color in ViewBag.ListColors)
{
<li><font color="@color">@color</font> </li>
}
</ul>
<p>
@ViewBag.DateNow
</p>

ViewBag跪削、ViewData 和 TempData 的區(qū)別:

ViewData 和 TempData 都可以傳遞弱類(lèi)型數(shù)據(jù),區(qū)別如下:

  • ViewData 只在當(dāng)前 Action 中有效迂求,生命周期和 View 相同碾盐;
  • TempData 的數(shù)據(jù)至多只能經(jīng)過(guò)一次Controller傳遞,并且每個(gè)元素至多只能被訪問(wèn)一次揩局,訪問(wèn)以后毫玖,自動(dòng)被刪除。
    -TempData 一般用于臨時(shí)的緩存內(nèi)容或拋出錯(cuò)誤頁(yè)面時(shí)傳遞錯(cuò)誤信息谐腰,可以將TempData 在使用之前存儲(chǔ)到相應(yīng)的 ViewData 中以備循環(huán)使用孕豹。

ViewBag

我們可以認(rèn)為 ViewBag=ViewData+Dynamic wrapper around the ViewData ,接下來(lái)你就可以體會(huì)到這個(gè)公式的含義了十气。

1励背、conroller向view傳值


4.png

2、view向view傳值:

5.png

3砸西、利用ViewBag傳遞一個(gè)對(duì)象:

6.png

ViewData

1叶眉、ViewData的基本用法

111.png

2、ViewData 轉(zhuǎn)換成 ViewBag:

222.png

3芹枷、ViewBag 轉(zhuǎn)換成 ViewData:

333.png

TempData

TempData用于在Redirect的時(shí)候保存數(shù)據(jù)衅疙,ViewData、ViewBag在跳轉(zhuǎn)后就會(huì)變成null鸳慈,但是TempData不會(huì)饱溢,下面是TempData的用法示例:

public ActionResult Index()
{
  var model = new Review()
            {
                Body = "Start",
                Rating=5
            };
    TempData["ModelName"] = model;
    return RedirectToAction("About");
}
<pre><pre lang="cs">public ActionResult About()
{
    var model= TempData["ModelName"];
    return View(model);
}

普通頁(yè)面?zhèn)鬟fmodel:

//Action代碼
public ActionResult Index()
{
  Product p = new Product();
  p.Name = "Toy";
  return View(p);
}

在View中調(diào)用的代碼:

Product : <%: ((Product)Model).Name %>

向強(qiáng)類(lèi)型試圖傳遞model

1、WebForm Engine的試圖的實(shí)現(xiàn):

//Aciton的代碼
public ActionResult Index()
{
  Product p = new Product();
  p.Name = "Toy";
  return View(p);
}

View中的代碼
聲明類(lèi)型

<%@ Page Inherits="System.Web.Mvc.ViewPage<Product>" %>

直接用Model調(diào)用該對(duì)象

<h2> Product Name: <%: Model.Name %> </h2>

2走芋、Razor Engine的實(shí)現(xiàn):

在Razor中聲明類(lèi)型的方式:

@model Mvc3App.Models.Product

在Razor中調(diào)用對(duì)象的方式:

<h2> Product: @Model.Name </h2>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末绩郎,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子翁逞,更是在濱河造成了極大的恐慌肋杖,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挖函,死亡現(xiàn)場(chǎng)離奇詭異状植,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)怨喘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)津畸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人必怜,你說(shuō)我怎么就攤上這事洼畅。” “怎么了棚赔?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵帝簇,是天一觀的道長(zhǎng)徘郭。 經(jīng)常有香客問(wèn)我,道長(zhǎng)丧肴,這世上最難降的妖魔是什么残揉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮芋浮,結(jié)果婚禮上抱环,老公的妹妹穿的比我還像新娘。我一直安慰自己纸巷,他們只是感情好镇草,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著瘤旨,像睡著了一般梯啤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上存哲,一...
    開(kāi)封第一講書(shū)人閱讀 51,488評(píng)論 1 302
  • 那天因宇,我揣著相機(jī)與錄音,去河邊找鬼祟偷。 笑死察滑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的修肠。 我是一名探鬼主播贺辰,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼嵌施!你這毒婦竟也來(lái)了饲化?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤艰管,失蹤者是張志新(化名)和其女友劉穎滓侍,沒(méi)想到半個(gè)月后蒋川,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體牲芋,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赞咙。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蟹地,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钩骇,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布卜高,位于F島的核電站弥姻,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏掺涛。R本人自食惡果不足惜庭敦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望薪缆。 院中可真熱鬧秧廉,春花似錦、人聲如沸拣帽。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)减拭。三九已至蔽豺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間峡谊,已是汗流浹背茫虽。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留既们,地道東北人濒析。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像啥纸,于是被迫代替她去往敵國(guó)和親号杏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容