由ASP.NET所谓前台调用后台、后台调用前台想到HTTP——实践篇(二)
在由ASP.NET所谓前台调用后台、后台调用前台想到HTTP——理论篇中描述了一下ASP.NET新手的三个问题及相关的HTTP协议内容,在由ASP.NET所谓前台调用后台、后台调用前台想到HTTP——实践篇(一)中已经解答了关于服务器怎么改变页面元素或“调用”JavaScript的问题,为了避免上篇啰啰嗦嗦一大推,这次直奔主题——ASP.NET前台如何调用后台方法
问题细化
所谓前台调用后台这种问题的提出无非是因为很多新手受了ASP.NET服务器端控件的“误导”,你不是说前台没有把JavaScript语句、页面元素什么的传到后台,所以前台调用后台,或者后台监视页面变化是扯淡嘛!那ASP.NET中为什么服务器端控件一点击就能调用后台制定方法呢?按照你前面的理论即使用了服务器端控件,那么到了浏览器页面也变成最普通不过的HTML文本了,怎么还能够调用服务器端方法呢?!
确实,浏览器呈现的是HTML文本,我们先不用拘泥于ASP.NET怎么做到的前台“调用”后台,我们可以自己实现一下,不过在此之前我们得明白一些过于Post的问题
简单聊聊Post
我们在看很多网页的时候都会看到这样的内容
<form id="form1" method="post" action="Default.aspx">
<input type="text" name="wd" />
<input type="submit" name="test" value="test" />
</form>
这段HTML文本同学们都能看懂,页面上有一个form,form内有两个input,点击submit的时候,页面form内容会以post方式被提交到Default.aspx这个页面。
HTTP协议中的Post方法会将所处的form提交到form指定页面,如果form指定的方法为post(还可能是get等),那么form内有些数据会一并被提交。
既然不是整个form被提交,那么哪些数据会被提交呢?
1.input的name和value
2.input type=”submit” 只有被点击的时候才将其本身name与value提交
3.对于多个name相同的input type=”checkbox”,只有选中项的值会被提交(多个value以,连接)
4.对于多个name相同的input type=”radio”,只有选中项的value会被提交(同名的radio只能单选)
5.select的name和被选中的option的vaue(不是option的text)
6.textarea 的name与value
这样被提交的数据可以在提交的页面的后台中以Request.Form[“name”]的方式查到其值
input type=”submit” “调用”后台方法
知道了form和post的最基本知识,我们就可以模拟ASP.NET的button调用后台方法了,首先准备这样一个页面
<form id="form1" method="post" action="Default.aspx">
<input type="submit" name="test" value="test"/>
</form>
在后台添加想调用的方法
protected void test_Click(object sender, EventArgs e)
{
Response.Write("Button Click!");
}
很简单的内容,后台方法的两个参数完全可以不用(和事件有关),填上只是为了增加其逼真性,代码中有几个需要注意的地方
1.form的方法需要设为post,这个很明显。。。
2.form的action设为页面本身,也就是让页面提交给自己
3.input要有name
准备工作做好后就可以模拟JavaScript调用后台方法了,在页面的 OnLoad方法中写入代码
protected override void OnLoad(EventArgs e)
{
if (Request.Form["test"]!=null)
{
test_Click(this, new EventArgs());
}
base.OnLoad(e); }
聪明的同学肯定可以看出端倪了,在点击test的时候会提交表单,页面的OnLoad会自动执行,这时候会判断提交过来的表单中是否包含test(submit被点击后会被提交,不点击不提交,所以可以根据name可以判断出哪个按钮被按了),就这么简单,点击submit的时候,预定义的方法就被调用了,要是页面上有很多submit,这时候就需要if-else或者switch或者for这样的东西来判断到底是哪个submit被点击了,然后调用对应方法。
asp: button
对比一下,ASP.NET正好用,首先人家的from是这样的
<form id="form1" runat="server">
</form>
人家自动就给render成这样了

我们也不需要自己在OnLoad中添加if-else,只要在control的属性中添加OnClick=”XXX”就可以了,我没看过.NET源码,但是我大胆的揣测,虽然不用再OnLoad里if-else了,但应该也是类似的方式处理。
不自动提交表单的怎么办
细心的同学可能要问了,你这么做是可以,但是依赖于表单提交,我们知道并不是所有的页面元素都会点一下就提交表单,像控件asp: DropDownList的OnSelectIndexChanged事件,人家也会调用回台方法,那是怎么做的?
其实非常简单,对于这种需求,仍然可以用表单提交的方式处理,不能自动提交表单,那么我们可以用JavaScript帮助其提交,看个select change “调用”后台函数的例子,首先像这样修改页面,添加一个select
<form id="form1" method="post" action="Default.aspx">
<input type="hidden" id="__param" name="__param" />
<input id="test" name="test" type="submit" value="test" />
<select id="select1" name="select1">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
<script type="text/javascript">
document.getElementById('select1').onchange = function () {
document.getElementById('__param').value = this.name;
document.getElementById('form1').submit();
};
</script>
</form>
我们除了select元素还添加了两个内容,一个input type=”hidden”的隐藏元素,一段JavaScript脚本,在JavaScript脚本中对select的onchange绑定了一个方法,当select选择项变化的时候,把其name赋值给隐藏域的value,然后提交表单,由于隐藏域可定会被提交,这样我们可以同样在页面的Onload中判断谁的onchange触发了,然后调用预定义方法,后台代码是这样的
protected override void OnLoad(EventArgs e)
{
string param= Request.Form["__param"];
if (Request.Form["test"]!=null)
{
test_Click(this, new EventArgs());
}
else if (param == "select1")
{
select_Change(this, new EventArgs());
}
base.OnLoad(e);
} protected void test_Click(object sender, EventArgs e)
{
Response.Write("Button Click!");
} protected void select_Change(object sender, EventArgs e)
{
string newValue = Request.Form["select1"];
Response.Write("Seclect value chaned to " + newValue);
}
是不是很简单呢?先判断是不是submit,不是的话判断隐藏域,命中后调用预定义方法。
细心的同学仍然会发现问题,要是一个元素上同时又两个事件怎么办?比如还想对这个select添加cilck事件怎么办,这时候我们可以修改隐藏域的值,不仅记录name,还记上事件类型,类似这样
document.getElementById('select1').onchange = function () {
document.getElementById('__param').value = this.name+"$ onchange";
document.getElementById('form1').submit();
};
document.getElementById('select1').onclick = function () {
document.getElementById('__param').value = this.name+"$ onclick";
document.getElementById('form1').submit();
};
然后在后台判断的时候,我们可以先把参数按$分割为两个字符串,分别判断元素与事件类型,当然我们也可以再添加一个隐藏域,用来记事件类型,大同小异。
还有同学回问,如果我在客户端同样写了select的onclick,不就把你的代码覆盖了吗?这样我就不能post了,对于这个问题我们大可以换种方式绑定事件处理程序,用addEventListener(attachEven)的方式,这样post的代码和自己写的客户端的就可以同时存在了,这样
var select = document.getElementById('select1');
select.onclick = function () {
//
//
//
};
select.addEventListener('clcik', function () {//浏览器兼容性问题要处理,这里就不演示了
document.getElementById('__param').value = this.name + "$ onclick";
document.getElementById('form1').submit();
}, false);
asp: DropDownList
我们可以看看ASP.NET是怎么处理的,在页面上写一个DropDownList,设起AutoPostBack属性为true
<form id="form1" runat="server">
<asp:DropDownList ID="ddlTest" runat="server" AutoPostBack="true">
<asp:ListItem>1</asp:ListItem>
<asp:ListItem>2</asp:ListItem>
<asp:ListItem>3</asp:ListItem>
</asp:DropDownList>
</form>
生成的页面源码是这样的
<html xmlns="http://www.w3.org/1999/xhtml"><head><title> </title><style type="text/css"></style></head>
<body cz-shortcut-listen="true">
<form method="post" action="Default.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="">
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="">
</div> <script type="text/javascript">
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script> <div class="aspNetHidden"> <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEdAAWUpg6MZl3t8/pBYubwqWOJqSwDGOXu15HYfC2efhAyHc1gIfz8erLrnvHjMLCTGHuRsEl8lEzJ1SVLtM7lgCLfggLVPRtDk70yN7TcfPOwwBRLeEs10HSMSLT9zq5aYmmjMFX5QrdQAuJDrw+EXFTJ">
</div>
<select name="ddlTest" onchange="javascript:setTimeout('__doPostBack(\'ddlTest\',\'\')', 0)" id="ddlTest">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option> </select>
</form> </body></html>
主要是这个方法,认真读读是不是和我们刚才写的类似呢,人家传了两个隐藏域,一个用来是Target,一个用来及参数
onchange="javascript:setTimeout('__doPostBack(\'ddlTest\',\'\')', 0)"
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
未完待续,与君共勉
通过上面例子分析可以看得出来,JavaScript根本没有调用后台函数,只是提交了含有预设参数的表单,服务器根据参数调用后台方法,生成特定HTML,所谓前台调用后台也就这么回事儿。
有一个问题值得思考,为什么这种很想当然的做法PHP程序员可以轻松想到,很多.NET初级程序员却不行,甚至有时候我们都已经在使用了,比如根据Url的QueryString来调用不同方法,或进行不同处理,却没有进一步想到更常用的Button、DropDownList是怎么做到的?还是那句话,.NET程序员当自勉,不要被.NET的易用性惯坏,多学习原理知识,不要过分满足于做出来,而要多追求为什么,这样才能不断进步。
由ASP.NET所谓前台调用后台、后台调用前台想到HTTP——实践篇(二)的更多相关文章
- ASP.NET前台JS与后台CS函数如何互相调用
摘要: 在实际的Web开发中,我们可能会常常遇到后台调用前台JS代码或者前台JS调用后台代码的情况.今天就把比较实用的前后台相互调用的方法总结出来和大家分享. 在实际的Web开发中,我们可能会常常遇到 ...
- ASP.NET所谓前台调用后台、后台调用前台想到HTTP——实践篇
由ASP.NET所谓前台调用后台.后台调用前台想到HTTP——实践篇 在由ASP.NET所谓前台调用后台.后台调用前台想到HTTP——理论篇中描述了一下ASP.NET新手的三个问题及相关的HTTP协议 ...
- js调用.net后台事件、后台调用前台以及js调用服务器控件
1. javaScript函数中执行C#代码中的函数: 方法一:间接触发后台代码 1.首先建立一个服务端控件按钮命名为btn1,双击进入后台将调用或处理的内容写入btn1_click中; 2.在前台写 ...
- Asp.net中前台javascript与后台C#交互
方法一:使用Ajax开发框架,后台方法定义前添加[AjaxPro.AjaxMethod],然后就可以在前台js脚本中调用后台C#函数. 方法二:后台方法声明为public或者protected,然后前 ...
- js调用.net后台事件,和后台调用前台等方法以及js调用服务器控件的方法
http://blog.csdn.net/deepwishly/article/details/6670942 ajaxPro.dll基础教程(前台调用后台方法,后台调用前台方法) 1. javaS ...
- Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员、后台管理员同时登录
1.登录的实现 登录功能实现起来有哪些常用的方式,大家首先想到的肯定是cookie或session或cookie+session,当然还有其他模式,今天主要探讨一下在Asp.net core 2.0下 ...
- ASP.NET前台代码绑定后台变量方法总结
经常会碰到在前台代码中要使用(或绑定)后台代码中变量值的问题.一般有<%= str%>和<%# str %>两种方式,这里简单总结一下.如有错误或异议之处,敬请各位指教. 一方 ...
- 转:ASP.NET前台代码绑定后台变量方法总结
经常会碰到在前台代码中要使用(或绑定)后台代码中变量值的问题.一般有<%= str%>和<%# str %>两种方式,这里简单总结一下.如有错误或异议之处,敬请各位指教. 一方 ...
- [ASP.NET] 前台代码绑定后台变量方法总结 [转]
原文链接:https://www.cnblogs.com/lerit/archive/2010/10/22/1858007.html 经常会碰到在前台代码中要使用(或绑定)后台代码中变量值的问题.一般 ...
随机推荐
- css3的transition过渡
从*开始样式*,经过指定*时间*后,缓慢过渡到*结束样式* 语法:transition:要变化的属性名 持续时间 速度变化类型 延迟 强调:写在开始样式中 如何实现多个属性同时过渡:2种办法: 1. ...
- iOS:小技巧(转)
记录下一些不常用技巧,以防忘记,复制用. 1.获取当前的View在Window的frame: 1 2 UIWindow * window=[[[UIApplication sharedApplicat ...
- JMeter压力测试入门教程[图文]
Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试但后来扩展到其他测试领域. 它可以用于测试静态和动态资源例如静态文件. ...
- Windows下 maven3.3.1的安装步骤+maven配置本地仓库
简单讲下maven的安装步骤: 1.在安装maven之前,先确保已经安装JDK1.6及以上版本,并且配置好环境变量. 2.下载maven3,最新版本是Maven3.3.1 ,下载地址:http://m ...
- Numpy 中一维数据转置的几种方法
把一个一维数组转置有如下几种方法.就是把 一行 n列的数组 转换成 n 行一列的数组, 如 如 [1,2,3,4] => [[1] [2] [3] [4]] 方法一: np.transpose ...
- DBCP配置数据库连接乱码问题
driverClassName = com.mysql.jdbc.Driver url = jdbc:mysql:///bigdata username = root password = 82371 ...
- Fix git 提交代码错误
今天用git clone下代码,修改,push提交,发现以下错误 [root@localhost gocache]# git push origin master error: The request ...
- viojs1908无线网路发射器选址
描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的 129 条东西向街道和 129 条南北向街道所形成的网格状,并且 ...
- being词典案例分析
一.调研评测: 1.软件bug: 1.输入空格分号回车之后并不给用户报错,说明他的异常处理机制有问题. 2.对于中文的很多口头语和方言,并不能给出翻译或者说,也并没有给出网络搜索后的结果. 3.添加生 ...
- 1.iOS直播ijkplayer(第一周)
准备工作: 1.使用的B站的开源框架ijkplayer ,下载地址: https://github.com/Bilibili/ijkplayer ijkplayer 是一个基于 ffplay 的轻量级 ...