在asp.net中客户端与服务器端的交互默认都是整页面提交,此时客户端将当前页面表单中的数据(包括一些自动生成的隐藏域)都提交到服务器端,服务器重新实例化一个当前页面类的实例响应这个请求,然后将整个页面的内容重新发送到客户端,这种处理方式对运行结果没什么影响,不过这种方式加重了网络的数据传输负担、加大了服务器的工作压力,并且用户还需要等待最终处理结果。

假如是我们希望有这么一个功能,当用户填写完用户名之后就检查服务器数据库里是否已存在该用户名,如果存在就给出已经存在此用户名的提示,如果不存在就提示用户此用户名可用,对于这种情况其实只需要传递一个用户名作为参数即可,上面的做法却需要提交整个表单,有点小题大做。

解决上面的问题的办法目前主流做法有三种:纯javascript实现、微软Ajax类库实现还有用AjaxPro实现。这里用另外一种实现:通过回调技术。

实现回调技术需要以下步骤:

(1)让当前页面实现ICallbackEventHandler接口,这个接口定义了两个方法:
string GetCallbackResult()方法和void RaiseCallbackEvent (string eventArgument)方法。其中GetCallbackResult ()方法的作用是返回以控件为目标的回调事件的结果,RaiseCallbackEvent()方法的作用是处理以控件为目标的回调事件。
(2)为当前页提供三个javascript客户端脚本函数。一个javascript函数用于执行对服务器的实际请求,在这个函数中可以提供一个字符串类型的参数发送到服务器端;另一个javascript函数用于接收服务器端方法的执行后返回的字符串类型结果,并处理这个结果;还有一个是执行对服务器请求的帮助函数,在服务器代码中通过GetCallbackEventReference()方法获取这个方法的引用时由asp.net自动生成这个函数。

1、实现ICallbackEventHandler

2、实现接口中的方法:RaiseCallbackEvent

3、实现接口中的方法:GetCallbackResult

方法

解释

参数

 void RaiseCallbackEvent(string eventArgument)  返回处理以控件为目标的回调事件  表示要传递到事件处理程序的事件参数
string GetCallbackResult() 返回以控件为目标的回调事件的结果

下面我以一个详细的例子来讲述如何使用回调,用Dreamweaver创建一个Register. aspx页面,代码如下:

单页模试实现回调代码

<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %> 
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>                         //注意这行
<%@ Import Namespace="System.Text" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/
xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 
<title>用户注册</title> 
<script language="javascript"> 
//客户端执行的方法 
//下面的方法是接收并处理服务器方法执行的返回结果 
function Success(args, context) 

    message.innerText  = args; 

//下面的方式是当接收服务器方法处理的结果发生异常时调用的方法 
function Error(args, context) 

    message.innerText  = '发生了异常'; 

</script> 
<script language="c#" runat="server"> 
string result=""; 
// 定义在服务器端运行的回调方法. 
public void RaiseCallbackEvent(String eventArgument) 
     //IndexOf()方法对大小写敏感,所以要用到ToLower()方法
     //把输入的与admin作比较,如果要检索的字符串值没有出现(也就是说不等于admin),则该方法返回 -1
     //admin123和123admin都不能注册;此处注意IndexOf的应用
     if(eventArgument.ToLower().IndexOf("admin")!=-1) 
      { 
           result=eventArgument+"不能作为用户名注册。"; 
      } 
     else 
     { 
           result=eventArgument+"可以注册。"; 
     } 
     //throw new Exception(); 

    //定义返回回调方法执行结果的方法 
public string GetCallbackResult() 

   return result; 

//服务器上执行的方法 
public void Page_Load(Object sender,EventArgs e) 

    // 获取当前页的ClientScriptManager的引用 
    ClientScriptManager csm = Page.ClientScript; 
    // 获取回调引用。会在客户端生成WebForm_DoCallback方法,调用它来达到异步调用。这个方式是微软写的方法,会被发送到客户端 
    //注意这里的"Success"和"Error"两个字符串分别客户端代码中定义的两个javascript函数 
    //下面的方法最后一个参数的意义:true表示执行异步回调,false表示执行同步回调 
    String reference = csm.GetCallbackEventReference(this, "args","Success","","Error",false); 
    String callbackScript = "function CallServerMethod(args, context) {\n" + reference + ";\n }"; 
    // 向当前页面注册javascript脚本代码 
    csm.RegisterClientScriptBlock(this.GetType(), "CallServerMethod", callbackScript, true); 

</script> 
</head> 
<body> 
<form id="form1" runat="server"> 
<table border="1" cellpadding="0" cellspacing="0" width="400px"> 
<tr> 
     <td width="100px">用户名</td>
     <td><input type="text" size="10" maxlength="20" id="txtUserName" 
          onblur="CallServerMethod(txtUserName.value,null)" />
     <span id="message"></span></td> 
</tr> 
<tr> 
     <td>密码</td>
     <td><input type="password" size="10" maxlength="20" id="txtPwd" /></td> 
</tr> 
</table> 
</form> 
</body> 
</html>

几点说明:(1)

<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>

这句表示当前页面实现了ICallbackEventHandler接口,如果采用页面与代码分离的模式,后台cs代码则应是:

 public partial class Register : System.Web.UI.Page, ICallbackEventHandler 
 { 
      //cs代码 
 }

(2)

<input type="text" size="10" maxlength="20" id="txtUserName" onblur="CallServerMethod(txtUserName.value,null)" />

这里有一个οnblur="CallServerMethod(txtUserName.value,null),表示当用户名文本框失去焦点之后激发CallServerMethod这个客户端方法,这个客户端方法是由asp.net动态生成的。
(3)

csm.GetCallbackEventReference(this, "args","Success","","Error",false);

中的"Success"和"Error"分别代表客户端的javascript函数,可以在代码中见到,其中"Success"代表调用服务器端方法成功后要执行的客户端方法名,"Error"代表调用服务器端方法失败时调用的客户端方法名。
该页面在客户端生成的HTML代码如下:

生成客户端HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>用户注册</title>
    <script type="text/javascript" language="javascript"> 
//客户端执行的方法
//下面的方法是接收并处理服务器方法执行的返回结果
function Success(args, context)
{
    message.innerText  = args;
}
//下面的方式是当接收服务器方法处理的结果发生异常时调用的方法
function Error(args, context)
{
    message.innerText  = '发生了异常';
}
</script>
</head>
<body>
    <form method="post" action="Register.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNzgzNDMwNTMzZGTZBYZOkBnHYrPqZwDocykE9kF/SOSZotkAOjqOBzODgg==" />
</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>
 
<script src="/Web/WebResource.axd?d=RAo7rL6tKkHnPnQX99wyRg2&amp;t=634095114802094502" type="text/javascript">
</script>
  
<script type="text/javascript"> 
//<![CDATA[
function CallServerMethod(args, context) {
WebForm_DoCallback('__Page',args,Success,"",Error,true);
 }//]]>
</script>

<table border="1" cellpadding="0" cellspacing="0" width="400px">
<tr>
<td width="100px">用户名</td><td><input type="text" size="10" maxlength="20" id="txtUserName"

                                  onblur="CallServerMethod(txtUserName.value,null)" /><span id="message"></span></td>
</tr>
<tr>
<td>密码</td><td><input type="password" size="10" maxlength="20" id="txtPwd" /></td>
</tr>
</table>
 
<script type="text/javascript"> 
//<![CDATA[
WebForm_InitCallback();//]]>
</script>
</form>
</body>
</html>

在生成的HTML代码中多了几段javascipt代码块,下面分别说明:
(1)第一部分

生成代码块

<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>

这部分代码是每个asp.net页面发送到客户端都会生成的,用于提交当前表单,其中eventTarget参数表示激发提交事件的控件,eventArgument参数表示发生该事件时的参数信息。
(2)第二部分

<script src="/Web/WebResource.axd?d=RAo7rL6tKkHnPnQX99wyRg2&amp;t=634095114802094502" type="text/javascript">
</script>

这部分代码是用来生成一些用于Ajax调用的js脚本。实际上asp.net之所以开发起来方便,是因为微软在幕后默默地为我们做了很多工作,回调的本质其实就是Ajax调用。 可以将WebResource.axd?d=RAo7rL6tKkHnPnQX99wyRg2&amp;t=634095114802094502" 复制到地址栏上,如图:

回车后弹出一个文件下载框如下图所示:

将这个页面保存到本地,虽然默认的保存文件的后缀为“.axd”,但它其实是一个文本文件,里面是一些javascript代码,可以用记事本打开,在里面我们可以看到“WebForm_DoCallback”这个方法,如下:

在这个axd文件里做了很多幕后工作,所以我们的回调才相对比较简单。
(3))第三部分

<script type="text/javascript"> 
//<![CDATA[
function CallServerMethod(args, context) {
WebForm_DoCallback('__Page',args,Success,"",Error,true);
 }//]]>
</script>

这部分代码是后台生成的,通过获取Page类的ClientScript属性,也就是ClientScriptManager的实例注册到页面的,里面定义了两个javascript函数:CallServerMethod函数和WebForm_DoCallback函数,并且是在CallServerMethod函数中调用WebForm_DoCallback函数。
(4)第四部分

<script type="text/javascript"> 
//<![CDATA[
WebForm_InitCallback();//]]>
</script>

这部分代码也是幕后生成的,这个javascript函数也可以在那个axd文件中找到。

转载于:https://www.cnblogs.com/aito/archive/2010/08/16/1800983.html

ASP.NET中的回调技术(CallBack)相关推荐

  1. 低调的华丽:从服务器开发的角度认识 asp.net 中的回调技术

    谈到异步调用,大家第一反应就是 ajax.这没有错,毕竟这是一个 ajax 的时代,ajax 以它最令人兴奋的客户端体验被大家普遍使用到 Web 开发中来.然而,我们知道,ajax 的本质仍是 Jav ...

  2. 理解javascript中的回调函数(callback)【转】

    在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实 ...

  3. 理解javascript中的回调函数(callback)

    理解javascript中的回调函数(callback) 在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Obje ...

  4. Asp.net中Postback及Callback

    我们知道,在默认的情况下,当我们点击Asp.net Page中的一个服务器Button时(默认其实是Submit Form),会导致Page被Recreated,这个过程我们称之为Postback,它 ...

  5. asp.net夜话之五:Page类和回调技术

    asp.net夜话之五:Page类和回调技术 在今天我主要要介绍的有如下知识点: Page类介绍 Page的生命周期 IsPostBack属性 ClientScriptManager类 回调技术(Ca ...

  6. 服务器响应回调函数,解决有关flask-socketio中服务端和客户端回调函数callback参数的问题(全网最全)...

    由于工作当中需要用的flask_socketio,所以自己学习了一下如何使用,查阅了有关文档,当看到回调函数callback的时候,发现文档里都描述的不太清楚,最后终于琢磨出来了,分享给有需要的朋友 ...

  7. C++中的Thunk技术 / 非静态类成员函数作为回调函数 的实现方法

    申明:本文非笔者原创,原文转载自:http://www.cnblogs.com/memset/p/thunk_in_cpp.html 用我的理解通俗地解释一下什么是C++中的Thunk技术吧! Thu ...

  8. .NET技术 ASP.NET中常用的文件上传下载方法(多文件上传)

    文件的上传下载是我们在实际项目开发过程中经常需要用到的技术,这里给出几种常见的方法,本文主要内容包括: 1.如何解决文件上传大小的限制 2.以文件形式保存到服务器 3.转换成二进制字节流保存到数据库以 ...

  9. Asp.net中的AJAX学习记录之一 AJAX技术的崛起与Asp.net AJAX的诞生

      最近开始学习Asp.net中的AJAX,可能我的高手朋友们会说:"走还不稳呢!怎么就想学跑了?"呵呵!主要是我在做项目中体会到AJAX真的是很好的一门技术,应该好好的学习一下, ...

最新文章

  1. mysql多列索引不全用,MySQL多列索引的生效规则
  2. SSH 安全性和配置入门
  3. windows:mysql5.7.29安装
  4. markdown编辑模式添加除水印图片方法
  5. 基于GRU和am-softmax的句子相似度模型 | 附代码实现
  6. LeetCode 7 整数反转
  7. 《堡垒之夜》中你可能没注意到的设计
  8. ES6的新特性(8)——数组的扩展
  9. 计算机器内存数量+引入和显示ARDS成员
  10. libxml2交叉编译问题及解决办法
  11. LeetCode 1055. 形成字符串的最短路径(贪心)
  12. 前端正则:常用正则表达式
  13. SQL优化笔记(二)—CPU优化
  14. 基于Zookeeper实现简易版服务的注册与发现机制
  15. output在delete中的应用
  16. 分布式系统的现代消息传递
  17. 常用cmd操作Redis的命令
  18. window7下visio 2013 64位激活工具
  19. 安卓快手批量取关软件v2.0
  20. 2020年8月程序员工资统计,平均14401元,下跌势头止住了

热门文章

  1. Android TableLayout
  2. log4j.properties文件示例
  3. 如何在Windows 10上安装Python
  4. amqp activemq_Spring AMQP ActiveMQ教程(第1部分)
  5. C++访问WebService
  6. Java基础篇:嵌套 if 语句
  7. 华三配置telnet
  8. HTML5中Audio使用踩坑汇总
  9. awk的基本使用方法
  10. JS -- http、https地址自动检测并添加为链接