本文大致講解mvc前后端的傳值方式,包括control向view啃憎、view向control先朦、以及action向action。
- 一.經(jīng)典回顧
- 二敢伸、Controller向View傳值
- 三扯饶、View向Controller傳值
- 四、Controller向Controller傳值(Action之間傳值)
- 五、與WebForms傳值的對(duì)比
- 六帝际、MVC 向頁(yè)面?zhèn)髦捣绞娇偨Y(jié)
一.經(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
用法:
在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
用法:
在Controller中書(shū)寫(xiě)
ViewData["Test123"] = "Hello World. This is ViewData";
前臺(tái)接收
@ViewData["Test123"]
說(shuō)明:ViewData是字典類(lèi)型快骗,繼承自IDictionary<string,object>接口
3. TempData
用法:
在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的值
//...
- TempData
TempData["userName"] = "zhangsan";
return RedirectToAction("Index2");
在Index2中接收:
string userName = TempData["userName"].ToString();
說(shuō)明:TempData可以在同Controller中不同Action之間傳遞溃槐,并且具有‘一次訪問(wèn)’的特質(zhì)匣砖。使用時(shí)要特別注意。
五昏滴、與WebForms傳值的對(duì)比
后臺(tái)不能通過(guò)非提交方式獲取某個(gè)頁(yè)面元素的值猴鲫,因?yàn)闆](méi)有‘服務(wù)器控件’;MVC使用原生Http谣殊,是【無(wú)狀態(tài)】的拂共。
不能使用(也沒(méi)有)ViewState。
使用特有的機(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傳值
2、view向view傳值:
3砸西、利用ViewBag傳遞一個(gè)對(duì)象:
ViewData
1叶眉、ViewData的基本用法
2、ViewData 轉(zhuǎn)換成 ViewBag:
3芹枷、ViewBag 轉(zhuǎn)換成 ViewData:
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>