ASP.NET Button控件的UseSubmitBehavior属性引发的血案
这里先不说标题上的UseSubmitBehavior属性是什么,先说下面这种情况。
通常,在我们写一个表单页面的时候,最下方会有“提交”和“返回”字样的两个按钮。顾名思义,它们的功能大家都知道,但是一般情况下我们会给表单的内容加上一些验证,这样就出现了一个问题。因为两个按钮是服务器控件(有runat=”Server”属性),所以点击按钮之后会先进行验证(无论这里你用的是前台的jQuery.validate验证或者是ASP.NET自带的后台验证控件验证,都会先进行验证)。对于“提交”按钮,这确实是我们想要的,但是对于“返回”按钮,我们并不想出现这种情况,而是想让它不经过验证,直接跳转回上一页。
对于这种情况,我以前的解决方法就是把
<asp:Button ID="button_back" runat="server" Text="back" OnClick="button_back_Click" />
换成
<input type="button" value="back" onclick="BackToPage();" />
这种形式。BackToPage方法实现页面跳转。
我相信很多朋友都是这么写的吧?反正能解决问题就行。为什么?往下看。
但是今天无意中发现了Button.UseSubmitBehavior这个属性,将其置成false,会使“返回”按钮“躲避”掉表单验证,直接执行点击事件中的方法。这正是我们一直以来想要的不是么?而且按钮还很统一,不用去加额外的js代码。
这里要说明一下,大家不要以为Button.UseSubmitBehavior真的是用来“躲避”验证的,我只是用这个词来表达一下它实现的效果。实际上Button控件有专门的属性是用来屏蔽验证控件的。就是Button.CausesValidation,通过名字我们应该就能了解一二。
那你会不会问,“既然有这个属性,以上问题就不算是问题啦,可以很容易的解决。”
我想说,“是这样的啊!”但前提是,你的项目中只存在后台验证。但是现实中我觉得不会所有人都这样做吧?反正我就蛮习惯用jQuery.validate验证插件的(前台验证)。那我们继续研究Button.UseSubmitBehavior吧。
看个例子:
前台代码:
<asp:Button ID="button_confirm" runat="server" Text="确定" />
<asp:Button ID="button_back" runat="server" Text="返回" onclick="button_back_Click" />
浏览器中查看源码中的形式
前台代码:
<asp:Button ID="button_confirm" runat="server" Text="确定" />
<asp:Button ID="button_back" runat="server" Text="返回" UseSubmitBehavior="false" onclick="button_back_Click" />
浏览器中查看源码中的形式
大家可以看出加上UseSubmitBehavior属性后,解析成的html语句明显不同。看到这我才恍然大悟,当加过UseSubmitBehavior属性之后,type属性变成了button,这样就跟以往的解决方法一样了啊,因为不是submit属性,所以也就不会触发jQuery.validate的验证方法(回答上面橙色加粗部分的为什么)。这就是为什么UseSubmitBehavior 置成false后,不用去进行前台验证的原因。这就是谜底。
但是到这就结束了会不会觉得有些怪呢?我们为了达到我们的目的,使用了一个新的属性,但是这个属性存在的意义并非是为了达到我们的目的。
整理一下思绪,上面的例子我们需要从脑袋里抹去。UseSubmitBehavior属性与是否触发表单验证完全没有任何关系。我们来专注这个属性的本身,毕竟这个是标题。
我很俗的查了一下MSDN
可以看出重点就是图里指出的两个机制:
1、客户端浏览器的提交机制
2、ASP.NET 回发机制
解释一下,有错误的话请大家指正
1、大家可以看下这个链接所讲的第一部分:http://www.th7.cn/Program/net/201309/150415.shtml
就是浏览器会封装一个请求报文,发给服务器,服务器解析这个报文,进行重组,生成一个响应报文,回发给浏览器,浏览器收到后再对其进行解析,就生成了我们看到的网页和一些我们看不到的数据。它们之间的通信都是遵循HTTP协议。
重点强调:HTTP是无状态协议,也就是说每次的浏览器请求,服务器响应都是全新的一次。
2、大家可以看下这个链接所讲的内容:http://blog.sina.com.cn/s/blog_7815564501012qgy.html 对于回发机制,我希望大家能跟着这篇文章里讲的步骤写个小Demo试试,会更有感觉。
回发机制,就是自己请求自己的页面,这个机制比较搞,如果大家理解上一个机制,就会发现ASP.NET回发机制与其是有点背离的,上一个是无状态的,这一个是能将前一次的值保存住,作为下一次页面的初值。
举个实际中的例子,就是当我们在填写一个表单时,有好多好多项,但是当我们填到倒数第二项的时候,不小心点击了刷新,正常按第一个机制来说,表单内控件上的值应该全部被清空,因为此时还没有做数据库读取的操作,所以页面不可能有值,但是有了回发机制,__viewstate把页面保存了下来,这样就保留下了我们先前填写的内容。不过技术群里的一个朋友说“现在这个东西已经很少会用了,基本不会用控件做项目开发。”囧rz啊~我一直都用的不亦乐乎,怎么破?
两个机制解释完了,可能大家还是有点一头雾水,其实此时我也是一样。下面写个Demo让整件事情变得更清晰点吧,借用一下Fiddler 这个工具。
页面展示:
html代码:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server" method="post">
<div>
<asp:Label ID="Label1" runat="server" Text="content:" ></asp:Label>
<asp:TextBox ID="textbox_content" runat="server" width="500px"></asp:TextBox>
<asp:Button ID="button_usesubmitbehavior_true" runat="server" Text="browser-server"
onclick="button_usesubmitbehavior_true_Click" />
<asp:Button ID="button_usesubmitbehavior_false" runat="server" Text="postback"
UseSubmitBehavior="false" onclick="button_usesubmitbehavior_false_Click" />
</div>
</form>
</body>
</html>
页面源码:
后台代码:
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
textbox_content.Text += "M";
} protected void button_usesubmitbehavior_true_Click(object sender, EventArgs e)
{
textbox_content.Text += "true";
button_usesubmitbehavior_true.Text += "1";
button_usesubmitbehavior_false.Text += "2";
} protected void button_usesubmitbehavior_false_Click(object sender, EventArgs e)
{
textbox_content.Text += "false";
button_usesubmitbehavior_true.Text += "3";
button_usesubmitbehavior_false.Text += "4";
} }
操作步骤:
1、初始页面
2、先连续点击browser-server按钮三次
3、再连接点击postback按钮三次。
通过这个demo示例,如果单从页面显示上看,我们完全看不到两者有什么不同,因为后台想实现的功能两者都实现了(就是点击一下按钮,会经过一次page_load方法,然后再经过各自的click事件,给文本框和两个按钮追加内容)。但是利用fiddler工具,我们会发现提交的表单内容的确是有些不一样,UseSubmitBehavior属性设为false的按钮提交时,本身没有作为表单的参数传递给服务器端。
这就是唯一的不同吗?感觉还是不够,不过我真的是写不动了。
有兴趣的朋友可以再想想别的对比示例,比如试试在page上加EnableViewState="false" 这个属性,看看点击完按钮会是什么效果的。这个我也有试,不过感觉还是不能证明什么。
啊,最后终于想到了一个,你可以给browser-server按钮加上EnableViewState="false"属性,嗯嗯,这个比较靠谱,给browser-server 按钮加上EnableViewState="false"属性 ,目的就是让其没有回发机制,因为Asp.Net控件默认都会有回发机制,这样browser-server 按钮就只有单纯的客户端浏览器的提交机制,而postback按钮就只有回发机制。页面效果异常明显啊~
卖个关子,想看效果的朋友自己去试一下吧,大家可以留言做交流,原谅我,这篇文章写的属实有点累。
总结一下,UseSubmitBehavior 这个属性绝对可以说是非主流的,花时间去研究会不会很蛋疼?
其实最初根本没有想过这篇文章会写这么长,但是随着研究这个属性深入,我去学习了ASP.NET的底层交互原理,ASP.NET页面生命周期,回发机制以及了解了验证相关的问题。说实话,收获蛮多的,也很开心。当然,还要继续实践,学习。
附件的链接:http://files.cnblogs.com/zhouhongyu1989/UseSubmitBehavior%E7%A4%BA%E4%BE%8BDemo.rar
ASP.NET Button控件的UseSubmitBehavior属性引发的血案的更多相关文章
- asp.net button控件 使用JS的 disabled
今天想用JS禁用asp.net的button控件,查了好久,都是一行代码.... document.getElementById("Button1").disabled ...
- 关于Button控件的CommandName属性用法的一个实例
注:本文分享于悠闲的博客,地址:http://www.cnblogs.com/9999/archive/2009/11/24/1609234.html 1.前台的代码 <%@ Page Lang ...
- asp.net GridView控件的列属性
BoundField 默认的数据绑定类型,通常用于显示普通文本 CheckBoxField 显示布尔类型的数据.绑定数据为TRUE时,复选框数据绑定列为选中状态:绑定数据为FALSE时,则显示未选中状 ...
- ASP.NET服务器端控件(class0617)
ASP.Net服务端基本控件介绍 ASP.Net服务端控件是ASP.Net对HTML的封装,在C#代码中就可以用txt1.Text=‘abc’这种方式来修改input的值,ASP.Net会将服务端控件 ...
- C# Windows - Button 控件
.Net Framework提供了一个派生于Control的类System.Windows.Forms.ButtonBase,它实现了Button控件所需的基本功能. System.Windows.F ...
- asp.net动态生成按钮Button控件
1.动态生成button控件及响应服务端和客户端事件 void BindButtons(){ foreach (var item in items) { Button Btn = new Button ...
- ASP.Net UpdatePanel控件(转)
Asp.net UpdatePanel 允许用户构建一个丰富的,以客户端为中心的应用程序,引用UpdatePanel控件,能够实现页面的部分刷新,一个包含scriptManage和 UpdateP ...
- ASP.Net 验证控件 RequiredFieldValidator
使用 ASP.NET 验证控件可在网页上检查用户输入.有用于各种不同类型验证的控件,例如范围检查或模式匹配验证控件.每个验证控件都引用网页上其他位置的输入控件(服务器控件).当处理用户输入时(例如,当 ...
- ASP.NET数据绑定控件
数据绑定控件简介 数据绑定分为:数据源 和 数据绑定控件 两部分,数据绑定控件通过数据源来获得数据,通过数据源来隔离数据提供者和数据使用者,数据源有:SqlDataSource,AccessDataS ...
随机推荐
- linux命令之文件备份与压缩命令
1.tar:打包备份 该命令是将多个命令打包到一起,并且可以实现解压打包.打包是将多个文件或者目录变成一个总的文件,压缩则是将一个大的文件通过压缩算法变成一个小文件. 参数 说明 z(常用) 通过gz ...
- php函数源代码 C编写 【持续更新】
由于经常被抓取文章内容,在此附上博客文章网址:,偶尔会更新某些出错的数据或文字,建议到我博客地址 : --> 点击这里 strlen() 获取字符串长度,成功则返回字符串 string 的长度 ...
- Elasticsearch学习(4) spring boot整合Elasticsearch的聚合操作
之前已将spring boot原生方式介绍了,接下将结介绍的是Elasticsearch聚合操作.聚合操作一般来说是解决一下复杂的业务,比如mysql中的求和和分组,由于博主踩的坑比较多,所以博客可能 ...
- 逻辑卷磁盘管理和dd命令
底层PV 中层VG 上层LV PE(phsical extent):在逻辑层次上,VG把PV分成固定大小的块,这些块就叫PE,默认为4M ,创建LV的过程就是分多少个PE的过程. 自动分区的过 ...
- Spring Boot 之 Hello World 战记
1. Maven创建SpringBoot项目 2. application.properties spring.session.store-type=none // 解决默认的30+编译错误 3. d ...
- 代码 | 自适应大邻域搜索系列之(4) - Solution定义和管理的代码实现解析
前言 上一篇讲解了destroy和repair方法的具体实现代码,好多读者都在喊酸爽和得劲儿--今天这篇就讲点简单的,关于solution的定义和管理的代码实现,让大家回回神吧--哈哈. 01 总体概 ...
- 后序线索化二叉树(Java版)
前面介绍了前序线索化二叉树.中序线索化二叉树,本文将介绍后序线索化二叉树.之所以用单独的一篇文章来分析后序线索化二叉树,是因为后序线索化二叉树比前序.中序要复杂一些:另外在复习线索化二叉树的过程中,大 ...
- 使用Chrome-headless模式下,截屏不全屏的问题
在headless模式下,是没有打开浏览器窗口的,那么driver.maximize_window(),找不到目标也打不开. 我们可以换一种方式,去在无头模式下,指定浏览器的窗口大小运行即可. __o ...
- Django-工程搭建
-----环境安装 1.创建虚拟环境 mkvirtualenv django_py3_1.11 -p python3 2.安装django pip install django==1.11.11 ...
- Oracle 11g
Oracle 11g 第一章 Oracle 11g数据库简介 1.1 认识Oracle11g Oracle 11g是Oracle 数据库最新的版本,目前已经被企业广泛的应用. 1.2 Oracl ...