2010年2月24日星期三

在 ASP.NET 网页中不经过回发而以编程方式实现客户端回调

客户端回调组件

创建以编程方式实现客户端回调的 ASP.NET 页与创建任何 ASP.NET 页的过程类似,但也存在下列区别。该页的服务器代码必须执行下列任务:

实现 ICallbackEventHandler 接口。可以向任何 ASP.NET 网页添加此接口声明。
提供 RaiseCallbackEvent 方法的实现。此方法将被调用以对服务器执行回调。
提供 GetCallbackResult 方法的实现。此方法会将回调结果返回给客户端。
此外,该页还必须包含执行以下操作的三个客户端脚本函数:

一个函数调用帮助器方法,该方法执行对服务器的实际请求。在此函数中,可以执行自定义逻辑,以最先准备事件实参。您可以将字符串作为形参发送给服务器端的回调事件处理程序。
另一个函数由处理回调事件的服务器代码的结果调用并接收该结果,同时接受表示该结果的字符串。此函数称为客户端回调函数。
第三个函数是执行实际服务器请求的 Helper 函数。当在服务器代码中使用 GetCallbackEventReference 方法生成对此函数的引用时,ASP.NET 将自动生成此函数。
客户端回调和回发都是针对原始页面的请求。因此,它们在 Web 服务器日志中被记录为页面请求。

在服务器代码中实现所需的接口
若要从客户端脚本中运行服务器代码而不执行回发,必须在服务器代码中实现一些接口。

声明 ICallbackEventHandler 接口
可以将 ICallbackEventHandler 接口作为页的类声明的一部分进行声明。如果创建代码隐藏页,则可以通过使用如下语法声明该接口。

      public partial class CallBack_DB_aspx :     System.Web.UI.Page, System.Web.UI.ICallbackEventHandle


如果正在处理单文件页或用户控件,则可以通过在页中使用 @ Implements 指令来添加声明,如下面的示例所示:


      <%@ Page Language="C#" %><%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>


注意:
接口名区分大小写。

创建服务器回调方法
在服务器代码中,必须创建一个实现 RaiseCallbackEvent 方法的方法和一个实现 GetCallbackResult 方法的方法。RaiseCallbackEvent 方法接受单个字符串参数,而不是通常用于事件处理程序的常见的两个参数。该方法的部分内容可能与下面的示例类似:

 
      public String RaiseCallbackEvent(String eventArgument){}


GetCallbackResult 不接受参数并返回一个字符串。该方法的部分内容可能与下面的示例类似:


      public string GetCallbackResult(){    return aStringValue;}


创建客户端脚本函数
必须向页中添加客户端脚本函数才能执行两个功能:向服务器页发送回调和接收结果。这两个客户端脚本函数都是用 ECMAScript (JavaScript) 编写。

发送回调
发送回调的函数在服务器代码中生成。实际回调由任何页都可使用的、实现 ICallbackEventHandler 接口的库函数执行。通过调用页的 GetCallbackEventReference 方法可以获取对库函数的引用,该方法可通过页 ClientScript 属性进行访问。然后动态生成一个客户端函数,该函数包含对来自 GetCallbackEventReference 方法的返回值的调用。应向该方法传递以下内容:一个对页的引用(在 C# 中为 this,在 Visual Basic 中为 Me)、传递数据时所使用的参数名称、将接收回调数据的客户端脚本函数的名称,以及传递所需的任何上下文的参数。

生成函数之后,通过调用 RegisterClientScriptBlock 方法将其插入到页中。

下面的示例演示如何以动态方式创建一个名为 CallServer 且调用回调的函数。

   void Page_Load(object sender, EventArgs e)
   { 

ClientScriptManager cm = Page.ClientScript;
   String cbReference = cm.GetCallbackEventReference(this, "arg",        "ReceiveServerData", "");
   String callbackScript = "function CallServer(arg, context) {" +        cbReference + "; }";
    cm.RegisterClientScriptBlock(this.GetType(),        "CallServer", callbackScript, true);
   }

由正在生成的函数接受的参数名称应与传递给 GetCallbackEventReference 方法的值的名称相匹配。

下面的示例演示了一些可用于调用回调并处理其返回值的标记:

      <input type="button" value="Callback"     onclick="CallServer(1, alert('Callback'))"/><br /><span id="Message"></span>

接收回调
可以编写在页中静态接收回调的客户端函数。该函数的名称必须与在 GetCallbackEventReference 方法调用中传递的名称相匹配。接收函数接受两个字符串值:一个用于返回值,另一个(可选)用于从服务器传回的上下文值。

该函数可能与下面的示例类似:

      <script type="text/javascript">function ReceiveServerData(arg, context){    Message.innerText = 'Processed callback.';}</script>
发表评论