菜单

Controller间数据的传递,NET内部机制

2019年8月2日 - 前端排行
Controller间数据的传递,NET内部机制

复制代码 代码如下:

图片 1

                                             浅谈ASP.NET内部机制(三)

<html>
<body>
 <form action=”login.action” method=”post”>
  <input type=”button” name=”btn” value=”提交表单” onclick=”return
sub();” />
 </form>
</body>
</html>
表单提交后,提交按钮不可用

返回主页

     前言:当我们把页面中的数据包含在表单中发送到服务器的时候,数据到底是以什么形式发送的?服务器接受到提交的数据后是如何读取这些数据,又是如何要决定来引发事件的?我们怎么样才能让我们自定义的控件能够在服务器端触发事件?为什么服务器控件有的要实IPostBackEventHandler,IPostBackDataHandler?…..

您可能感兴趣的文章:

雪飞鸿

 

博客园

系列文章链接:

浅谈ASP.NET的内部机制(一)

浅谈ASP.NET的内部机制(二)

浅谈ASP.NET内部机制(三)

浅谈ASP.NET内部机制(四)

浅谈ASP.NET内部机制(五)

浅谈ASP.NET内部机制(六)

浅谈ASP.NET内部机制(七)

浅谈ASP.NET内部机制(八)

新随笔

     大家已经在知道,在我们开发ASP.NET网站的时候,每个服务器控件都有自己的ID。为了后面更好的展开,下面我们就来简单的看看这个场景:当我们在浏览器中点击了一个服务器控件,如
Button,此时页面回传给服务器,然后服务器就引发控件的Click等事件,这个场景是简单的不能在简单了。我们来进一步看,我们知道,不是所有的控件都会在服务器端触发事件的,比如
submit按钮,这个按钮也同样可以把表单数据传到服务器,但是这个控件不能在服务器端触发事件。其实在一个页面提交到了服务器之后,服务器就会检查是哪个控件引起了页面提交,然后就把这个控件的ID找到,然后再在我们请求的那个页面,如Default.aspx
(假设我们点击按钮,请求的是Default.aspx),去找是否有服务器控件的ID和此时提交页面的ID是一样的,如果有,那么就在页面的生命周期的合适的时候,引发事件,在把处理的结果返回;如果没有,服务器就不做什么了特别的处理。

管理

 

ASP.NET MVC5中View-Controller间数据的传递

     还有一点要注意的是,在查找那个控件的ID
的时候,页面(如Default.aspx),已经被编译成为了一个继承自Page的类

使用ASP.NET
MVC做开发时,经常需要在页面(View)和控制器(Controller)之间传递数据,那么都有哪些数据传递的方式呢?
本文对于View向Controller中传值共列举了以下几种方式:
QueryString
RouteData
Model BindingForm
使用和Action参数同名的变量进行传递

     当然,上面说的只是一个很粗略额过程,希望大家有个总体的认识。下面就细致的讲解。

Cookie

 

对于Controller向View中传值则列举了以下几种方式:
单个值的传递
Json
匿名类型
ExpandoObject
ViewBag、ViewData、TempData
ViewModel
Cookie

     我通过一个流程来解释:

View向Controller中传递数据的方式
QueryString
View中代码:

     1.我们首先请求一个服务器端的页面,如:。为了方便解释,假设页面只有三个服务器控件:TextBox,DropDowmList,Button

图片 2

     定义如下:

复制代码

     

<div> <button
id=”btn”>提交</button></div><script> $(function ()
{ $(‘#btn’).click(function () { //url不区分大小写 location.href =
“/home/getvalue?method=querystring”; }); });</script>

 

图片 3

<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “;
<html xmlns=”;
<head runat=”server”>
<title>Untitled Page</title>
</head>
<body>
<form id=”form1” runat=”server”>
     <asp:TextBox runat=”server” ID=”TextBox1” />

复制代码

     <asp:DropDownList runat=”server” ID=”DropDownList1”>
     <asp:ListItem Text=”Text1” Value=”Value1” />
     <asp:ListItem Text=”Text2” Value=”Value2” />
     <asp:ListItem Text=”Text3” Value=”Value3” />
     </asp:DropDownList>

Controller中代码:
public void GetValue(){
//Request属性可用来获取querystring,form表单以及cookie中的值 var
querystring = Request[“method”];}

     <asp:Button runat=”server” Text=”Submit” />
</form>
</body>
</html>

使用querystring向后台传递属于http协议中的get方式,即数据会暴露在url中,安全性不高(可通过浏览器历史记录看到发送的数据)且传递的数据量有大小限制。点击提交按钮后浏览器地址栏中的地址:http://localhost:57625/home/getvalue?method=querystring。程序执行结果如下:

 

图片 4

     在浏览器中,我们在”源“中,看到的如下:

RouteData
路由可以让我们写出可读性较高的url,使用路由传递数据,首先要配置合适的路由:
routes.MapRoute( name: “Default”, url: “{controller}/{action}/{id}”);

     

前端代码只需要将location.href
的值改为和路由匹配的url即可,本示例中为”/home/getvalue/100″
Controller中的代码:
public void GetValue(){ var value = RouteData.Values[“id”];}

 

获取的值是object类型:

 

图片 5

图片 6图片 7Code
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“;
<html xmlns=”;
<head>
<title>Untitled Page </title>
</head>
<body>
<form name=”form1” method=”post” action=”Default7.aspx” id=”form2”>
<div>
<input type=”hidden” name=”__VIEWSTATE” id=”__VIEWSTATE”
value=”/wEPDwUKMTAxNzk2MjY2OWRkxj+0HeO0c5N0xVutp03x6OdaSpw=” />
</div>
<input name=”TextBox1” type=”text” id=”TextBox1” />
<select name=”DropDownList1” id=”DropDownList1”>
<option value=”Value1”>Text1</option>
<option value=”Value2”>Text2</option>
<option value=”Value3”>Text3</option>
</select>
<input type=”submit” name=”ctl02” value=”Submit” />
</form>
</body>
</html>

获取路由参数的另外一种方式是给Action设置一个和路由模板中指定的参数名一致(不区分大小写)的参数即可,代码如下:
public void GetValue(int id){}

 

注意,这里不仅获取了路由数据,而且自动将数据类型转换为int类型:

 

图片 8

     确实,上面的那些HTML的代码确实没有什么,但是大家注意看看TextBox,DropDownList,它们的ID在服务器端的aspx页面和本地的源中的ID是一样的。

querystring和路由均是通过url进行数据的传递,若数据中包含中文应进行Encode操作。此外,url的长度是有限制的,使用url不可传递过多的数据。url传递参数属于Http协议中的Get请求,若要发送大量数据可以使用Post请求。
ModelBinding
1. Form
form表单形式是常见的向后端发送数据的方式,但是在提交数据是只会提交form表单内部具有name属性input,textarea,select标签的value值。View中的代码:
<form action=”/home/getvalue” method=”post”> <input type=”text”
name=”username” /> <input type=”text” name=”age” /> <input
type=”submit” name=”button” value=”提交” /></form>

     2.我们在浏览器中的TextBox中输入”xiaoyang”,然后DropDowList
选中”Text2″,然后我们点击按钮,提交。此时我们提交的数据被包含在表单中的,而且是以这样的格式保存的”TextBox1=xiaoyang&DropDownList1=Value2″,不用多说,表单数据是用”&”来分隔的,而且每个分隔的串包含两个部分:ID和值,也就是”键值对”。

Controller中的代码:

     3.数据到了服务器后,ASP.NET就实例化一个
HttpRequest的类,这个类有两个属性 Forms和
QueryString,它们的类型都是NameValueCollection(键值对,大家可以把它看成一个HashTable),然后ASP.NET解析表单数据,表单数据就解析成为了一个个的键值对,然后就保存在Forms(POST提交)或者QueryString中(GET提交)。我们之前是以POST提交为例子的。

图片 9

     4.之前的事情是发生在页面的生命周期之前的。当页面调用自己的ProcessRequest方法后,就进入了页面生命周期,此时页面就会检查页面中的所有控件,看看它们有哪些实现了IPostBackDataHandler接口,然后把实现了这些接口的控件都放入到一个ArrayList中,然后也检查哪些控件实现了IPostBackEventHandler,也把它们假如到另外的集合中,之后就开发遍历实现了IPostBackDataHandler控件的集合,并且调用IPostBackDataHandler的方法:LoadPostData(string
postdatakey,NameValueCollection value)。

复制代码

     之前说过了的,我们提交的表单的值都保存在了Forms中(它的类型是NameValueCollection
的),所以此时这些值就传入到了这个方法,然后就检查这些值和之前的是不是相同的,我们已经还记得,我们在浏览器中看到页面时,页面中的TextBox
初始时是没有值的,而且DropDownList选择的是Text2,现在我们的值改了,是“xiaoyang”和”Text2″.所以这个方法检查的结果是:值变了,返回了true.只要返回了true,那么IPostBackDataHandler的下一个方法就会调用RaisePostDataChangeEvent();这个方法已经注册了事件,到页面生命周期的之后就后引发的。

public void GetValue(){ var name = Request[“username”]; var age =
Request[“age”]; var btn = Request[“button”];}

     5.所以,如果我们开发的自定义控件想要在数据改变的时候引发事件,那么就一定要实现IPostBackDataHandler接口。例子可以参看我的另外的控件开发的系列文章。

图片 10

     6.现在我们已经说到了数据的改变。下面就看看到底是怎么引发事件的。到了页面开发执行RaisePostbackEvent方法的时候,页面就会遍历实现了IPostBackEventHandler的控件的集合,并且检查是否在页面中存在一个控件:这个控件要实现了IPostBackEventHandler,并且ID和之前使得页面提交到服务器的的那个控件的ID一样。如果有IPostBackEventHandler的RaisePostBackEvent
方法来触发事件(不同控件实现这个方法的方式不同),如Click事件。

复制代码

     所以,如果想在自定义控件可以触发事件,那么就要实现IPostBackEventHandler接口。可以参看我的控件开发系列文章,有例子的。

获取到的数据均为string类型:

 

图片 11

     今天到这里!谢谢大家。

现在我们创建一个和form表单对应的类:
public class User{ public string UserName { set; get; } public int Age {
set; get; }}

修改Action的代码如下:
public void GetValue(User user){}

然后运行程序,可以看到MVC以将表单中的数据映射为User类实例的属性值,且进行了相应的数据类型的转换。

图片 12

  1. 使用和Action参数同名的变量进行传递
    View中的代码:
![](https://upload-images.jianshu.io/upload_images/8512409-b3a47a359c8d1e80.gif)

复制代码



&lt;button id="btn"&gt;传递数据&lt;/button&gt;&lt;script&gt;
$(function () { $('\#btn').click(function () { $.ajax({ 'type':
'post', 'url': '/home/getdata',
//传递的数据也可以是序列化之后的json格式数据
//如,上面使用form表单提交数据就可以使用jquery中的serialize()方法将表单进行序列化之后在提交
//data:$('\#form').serialize() 'data': { username: '雪飞鸿', age:
'24' }, error: function (message) { alert('error!'); } }); })
})&lt;/script&gt;



![](https://upload-images.jianshu.io/upload_images/8512409-b3a47a359c8d1e80.gif)

复制代码

Controller中的代码:
public void GetData(string username, int age){}

在Action中成功获取到了对应的参数值,且数据类型也根据Action中参数的类型进行了相应的转换。

Model绑定体现在从当前请求提取相应的数据绑定到目标Action方法的同名参数中。对于这样的一个Action,如果是Post请求,MVC会尝试将Form(注意,这里的Form不是指html中的<form>表单,而是Post方法发送数据的方式,若我们使用开发者工具查看Post方式发送的请求信息,会看到Form
Data一栏)中的值赋值到Action参数中,如果是get请求,MVC会尝试将QueryString的值赋值到Action参数中。

Cookie
这里引用jquery.cookie插件来进行cookie的操作

图片 13

复制代码

<body> <button id=”btn”>提交</button> <script>
$(function () { //向cookie中写入值 $.cookie(‘key’, ‘jscookie’);
$(‘#btn’).click(function () { location.href = “/home/getvalue”; }); })
</script></body>

图片 14

复制代码

public void GetValue(){ var cookie = Request[“key”];}

图片 15

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图