MVC&WebForm对照学习:传值方式
刚从webform开发转到mvc,如果说像路由这样稍微复杂一点的知识点还可以暂时先放一放(前提是默认的路由规则基本满足大部分需求),那有个问题在快速开发中,我想是必须要当即解决的,那就是webform中的传值方式是否同样适用于mvc中。那么本文照旧分两部分来阐述。接下来先简单快速地回顾webform中的传值方式。
Part 1 WebForm中的传值方式
Form表单传递(get/post)
//aspx <input type="text" id="txtName" name="txtName" runat="server"/> //aspx.cs string txtName = Request.Form["txtName"].ToString(); //隐藏域(以html服务器控件为例) <input type="hidden" id="hdUserId" runat="server" /> hdUserId.Value = "1";
1 页面间链接和数据传递的三种方式 2 (1)通过form将数据提交到下一个页面; 3 (2)通过链接将数据提交到下一个页面; 4 (3)通过Session将数据提交到后续页面,session是一次会话只要浏览器不关闭就不会关闭会话,一般默认保存30分钟可以根据自己的需要更改 。 5 例: 6 01.html 7 <html> 8 <head> 9 <title>利用表单传递数据</title> 10 </head> 11 <body> 12 <h3>利用表单传递数据</h3> 13 <form name="form1" method="post" action="02.jsp"> 14 <p>你的姓名: 15 <input type="text" name="name"> 16 </p> 17 <p>你的爱好: 18 <input type="text" name="hobby"> 19 </p> 20 <p>你所从事的行业: 21 <select name="work"> 22 <option></option> <!--默认为空,从下拉菜单中选择--> 23 <option value="学生">学生</option> 24 <option value="IT业">IT业</option> 25 <option value="商业">商业</option> 26 <option value="制造业">制造业</option> 27 <option value="服务业">服务业</option> 28 </select> 29 </p> 30 <p> 31 <input type="Submit" value="提交"> 32 <input type="Reset" value="重置"> 33 </p> 34 </form> 35 </body> 36 </html> 37 38 39 02.jsp 40 <html> 41 <head> 42 <title>从表单中获取数据</title> 43 </head> 44 <%@ page contentType="text/html;charset=GB2312"%> 45 <body> 46 <h3>从表单中获取数据</h3> 47 <p> 48 <% 49 //从表单中获取数据 50 String name= request.getParameter("name"); 51 String hobby=request.getParameter("hobby"); 52 String work= request.getParameter("work"); 53 //验证"名字(name)"的长度是否符合要求 54 if(name.length()<3||name.length()>8) 55 out.println("你输入的名字长度不符合要求"); 56 else 57 { 58 out.println("你的姓名是:"+name+"<br>"); 59 out.println("你的爱好是:"+hobby+"<br>"); 60 out.println("你所从事的工作是:"+work+"<br>"); 61 //将"名字(name)"保存到session对象中,让后续页面(下个页面、下下个页面、……)引用 62 session.setAttribute("name",name); 63 } 64 %> 65 <br> 66 <!--将"爱好(hobby)"和"工作(work)"以链接的形式传递给下个页面--> 67 <a href="03.jsp?hobby=<%=hobby%>&work=<%=work%>">提交</a> 68 </p> 69 <hr> 70 <p><font size="2">*将"名字(name)"保存到session对象中,让后续页面(下个页面、下下个页面、……)引用</font></p> 71 <p><font size="2">*将"爱好(hobby)"和"工作(work)"以链接的形式传递给下个页面</font></p> 72 </body> 73 </html> 74 75 03.jsp 76 <html> 77 <head> 78 <title>从session对象中获取"名字(name)"的值;从链接中获取"爱好(hobby)"和"工作(work)"</title> 79 </head> 80 <%@ page contentType="text/html;charset=GB2312"%> 81 <SCRIPT language="JavaScript"> 82 function submit1() 83 { 84 document.forms["form1"].action="04.jsp"; 85 document.form1.submit(); 86 } 87 88 function edit1() 89 { 90 document.forms["form1"].action="01.jsp"; 91 document.form1.submit(); 92 } 93 </SCRIPT> 94 <%@ page contentType="text/html;charset=GB2312" %> 95 <body> 96 <h3>从session对象中获取"名字(name)"的值;从链接中获取"爱好(hobby)"和"工作(work)"</h3> 97 <% 98 String name=(String)session.getAttribute("name"); 99 String hobby=request.getParameter("hobby"); 100 String work= request.getParameter("work"); 101 out.println("你的姓名是:"+name+"<br>"); 102 out.println("你的爱好是:"+hobby+"<br>"); 103 out.println("你所从事的工作是:"+work+"<br>"); 104 //将"爱好(hobby)"和"工作(work)"保存在session对象中 105 session.setAttribute("hobby",hobby); 106 session.setAttribute("work",work); 107 %> 108 <form name="form1" method="post"> 109 <input type="hidden" name="name" value="<%=name%>"> 110 <input type="hidden" name="hobby" value="<%=hobby%>"> 111 <input type="hidden" name="work" value="<%=work%>"> 112 <p><h3>确认提交这些信息吗?</h3></p> 113 <input type="Button" name="Submit" value="确认" onClick="javascript:submit1()"> 114 <input type="Button" name="Edit" value="修改" onClick="javascript:edit1()"> 115 </form> 116 <hr> 117 <p><font size="2">*将"爱好(hobby)"和"工作(work)"保存在session对象中,让后续页面(下个页面、下下个页面、……)引用</font></p> 118 <p><font size="2">*由于"名字(name)"在上个页面中已经保存在session对象中了,这里没必要再次保存</font></p> 119 </body> 120 </html> 121 122 04.jsp 123 <html> 124 <head> 125 <title>从sessoin对象中获取数据</title> 126 </head> 127 <%@ page contentType="text/html;charset=GB2312" %> 128 <body> 129 <h3>从sessoin对象中获取数据</h3> 130 <% 131 //从sessoin对象中获取数据 132 String name=(String)session.getAttribute("name"); 133 String work=(String)session.getAttribute("work"); 134 String hobby=(String)session.getAttribute("hobby"); 135 %> 136 <p> 137 <font color="#0000FF"><%=name%></font>,你好!你所从事的工作是<font color="#0000FF"><%=work%></font>,在业余时间喜欢<font color="#0000FF"><%=hobby%></font>。 138 </p> 139 </body> 140 </html> 141 142 01.jsp 143 <html> 144 <head> 145 <title>利用表单传递数据</title> 146 </head> 147 <%@ page contentType="text/html;charset=GB2312" %> 148 <% 149 String name=request.getParameter("name"); 150 String hobby=request.getParameter("hobby"); 151 String work=new String(request.getParameter("work").getBytes("ISO8859_1"),"GBK"); 152 %> 153 <body> 154 <h3>利用表单传递数据</h3> 155 <form name="form1" method="post" action="02.jsp"> 156 <p>你的姓名: 157 <input type="text" name="name" value="<%=name%>"> 158 </p> 159 <p>你的爱好: 160 <input type="text" name="hobby" value="<%=hobby%>"> 161 </p> 162 <p>你所从事的行业: 163 <select name="work"> 164 <%if(work.equals("学生")){%> 165 <option value="学生" selected>学生</option> 166 <option value="IT业">IT业</option> 167 <option value="商业">商业</option> 168 <option value="制造业">制造业</option> 169 <option value="服务业">服务业</option> 170 <%}else if(work.equals("IT业")){%> 171 <option value="学生">学生</option> 172 <option value="IT业" selected>IT业</option> 173 <option value="商业">商业</option> 174 <option value="制造业">制造业</option> 175 <option value="服务业">服务业</option> 176 <%}else if(work.equals("商业")){%> 177 <option value="学生">学生</option> 178 <option value="IT业">IT业</option> 179 <option value="商业" selected>商业</option> 180 <option value="制造业">制造业</option> 181 <option value="服务业">服务业</option> 182 <%}else if(work.equals("制造业")){%> 183 <option value="学生">学生</option> 184 <option value="IT业">IT业</option> 185 <option value="商业">商业</option> 186 <option value="制造业" selected>制造业</option> 187 <option value="服务业">服务业</option> 188 <%}else if(work.equals("服务业")){%> 189 <option value="学生">学生</option> 190 <option value="IT业">IT业</option> 191 <option value="商业">商业</option> 192 <option value="制造业">制造业</option> 193 <option value="服务业" selected>服务业</option> 194 <%}%> 195 </select> 196 </p> 197 <p> 198 <input type="Submit" value="提交"> 199 <input type="Reset" value="重置"> 200 </p> 201 </form> 202 </body> 203 </html>
以上仅仅使用文本标签和隐藏域为例。只要通过Form表单提交的的数据(包含隐藏域),不论是什么标签。都属于这种传值方式。
URL传递
1.超链接(以html标签为例): <a href="Default.aspx?param1=1111¶m2=2222">Go</a> 2.PostBackUrl <asp:Button ID="btnCheckOut" Text="CheckOut" PostBackUrl="~/Default.aspx?UserId=1" runat="Server" /> //get var userId=Request.QueryString["UserId"]
以上仅以<a>标签和PostBckUrl带参数传递为例。所有的这些通过url地址栏传递参数的都是URL传值。
内置对象传递
1.Response.Redirect //page1 string url = "Default.aspx?p1=" + p1 + "&p2=" + p1; Response.Redirect(url, false); //page2 var p1 = Request.QueryString["p1"].ToString(); var p2 = Request.QueryString["p2"].ToString(); 2.Server.Transfer //Default.aspx <input type="text" id="txtName" runat="server" /> //Default.aspx.cs Server.Transfer("~/Default2.aspx", true); Server.Execute("~/Default2.aspx", true); //Default.aspx.cs Page_Load Response.Write(Request.Form["txtName"]) 3.Session: //set Session["name"] = txtName.Value; //get string name = Session["name"].ToString(); 4.Cookie: //set HttpCookie cookie = new HttpCookie("MyCookie", aa); Response.Cookies.Add(cookie); //get HttpCookie myCookie = Request.Cookies["MyCookie"]; txt1.Value = myCookie.Value; 5.Cache 关于这个我不做叙述,详细的用法可以看 细说 ASP.NET Cache 及其高级用法 6.Application //set Application["count"] = 12; //get int count= (int)Application["count"].;
7.ViewState
关于这个话题,我不做过多叙述,可以看下这篇文章
Cross Page Posting (ASP.NET 2.0)
两个概念CrossPageSource.aspx(来源网页) CrossPageTarget.aspx(目标网页) 1.获取来源网页的控件的值 //Default.aspx(来源网页) <input type="text" id="txtName" runat="server" /> <asp:Button Text="test" runat="server" PostBackUrl="~/Default2.aspx" /> //Default2.aspx.cs(目标网页) if (PreviousPage.IsCrossPagePostBack) { //获取来源页的控件的值 Response.Write(Request.Form["txtName"]); //or Response.Write((PreviousPage.FindControl("txtName") as System.Web.UI.HtmlControls.HtmlInputText).Value); } 2.获取源网页属性值 //Default.aspx(来源网页) <input type="text" id="txtName" runat="server" /> <asp:Button Text="test" runat="server" PostBackUrl="~/Default2.aspx" /> //Default.aspx.cs 公共属性 public string Name { get { return txtName.Value; } } //Default2.aspx(目标网页) <%@ PreviousPageType VirtualPath="~/Default.aspx" %> //Default2.aspx.cs if (PreviousPage.IsCrossPagePostBack) { //获取属性的值 Response.Write(PreviousPage.Name); } 注:PreviousPage需要做非空判断
Part 2 MVC传值方式
在开始了解asp.net mvc各种传值方式之前,我们先来看下面这张图。它很形象的阐明了各个级别之间传递值的方式。
(来自互联网)
从图上不难看出asp.net mvc中独有的传值方式有ViewData、ViewBag、TempData。当然还有ViewModel和Model。当然细心的你可能发现这个图并不完美。稍作改动如下:
ViewData\ViewBag
关于它们两个我们先来看一组对照:
(图片来自互联网)
虽然ViewBag在asp.net mvc 3才出现,但它实质上它其实是一个包了一层Dynamic的ViewData(关于这个,可以看看这个,这里就不再细述),也就是对ViewData的封装,这样再看它们之间的差异时,我们就不难理解了。接下来看示例:
Action:
public ActionResult Index() {
ViewData["Message1"] = "This Message is coming from ViewData";
ViewBag.Message = "This Message is coming from ViewBag";
return View();
}
View:
<div>
@ViewData["Message1"]
</div>
<div>
@ViewBag.Message
</div>
上面讲到VieBag实质上其实是一个包了一层Dynamic的ViewData,而我们对ViewBag的动态属性进行赋值,值实际上是存到了ViewData中,动态属性的名存成了ViewDataDictionary的键,动态属性的值存成了ViewDataDictionary的值。为了论证这一点,我们将上面的代码做下的改动,再看运行结果:
果不其然,如同变量被重新赋值。由于实际上它们key同名了,而最终又是都是ViewDataDictionary的方式来存储的,所以后来的值将原先的给覆盖掉了。同样的道理,即使后台不做改动,我们在前台通过@ViewData["Message"]取到的是ViewBag.Message的值:
小结:ViewData、ViewBag主要是将数据从控制器级别传递到视图级别
TempData
TempData是TempDataDictionary的字典类型。它不仅可以将数据从action传递到视图,还可以传递到后续请求的action操作。接下来看示例:
(控制器)
(视图)
为了直接说明TempData可以将数据从一次请求传递到后续请求以及从控制器传递到视图,我直接在TestTempData操作中创建TempData["BookData"],然后传递到Index操作中,然后在Index的视图中展现数据。运行结果如下:
接下来,我们尝试刷新页面,很不幸的事情发生了:未将对象引用到对象的实例。调试发现TempData的值已经变为null:
之所以会这样这是由TempData的生命周期决定的:TempData只能保存数据到它的下一次请求。这其实是由TempData的存储机制有关。关于TempData的实现机制可以看下下面这篇文章: 浅谈ASP.NET MVC中TempData的实现机制 。当然asp.net mvc同样为我们提供了TempDaa持续保存数据的实现方式:
public ActionResult Index()
{
Book book = TempData["BookData"] as Book;
TempData.Keep("BookData");
//保存tempdate的值
return View(book);
}
View Code这也是基于TemData的实现机制,在下一次请求之前会移除TempData中任何没有被更新的键值对。于是我们通过keep对响应的key进行更新。
ViewModel
public ActionResult Index()
{
Book book = TempData["BookData"] as Book;
TempData.Keep("BookData");
//保存tempdate的值
return View(book);
}
视图:
<div>
ID: @Model.ID<br />
BookName:@Model.BookName<br />
Author: @Model.Author<br />
ISBN: @Model.ISBN
</div>
运行结果:
其它的像Session、Application、Cookie、Cache因为是基于asp.net框架的,和webform中使用的方式是一样的,这里就不做赘述。
注:由于个人技术有限,对某些概念的理解可能会存在偏差,如果你发现本文存在什么bug,请指正。谢谢!
完。