创立一个简单的客户端回调
为了在ASP.NET中展示一个客户端回调的实例,首先我们将概述客户端回调间的交互过程是怎么实现的。下面是基础的步骤:
1. 在某时刻激活一个JavaScript事件,从而触发客户端回调。
2. 触发客户端回调产生后,服务器真个一个方法将被执行。该方法有一个固定的模式――它接受的是一个字符串参数,并且返回的也是一个字符串参数。
3. 一旦页面接受到来自服务器端方法的响应成果后,它就可以利用JavaScript修改一些和用户界面有关的资讯(例如显露在页面上显露返回的成果)
对于开发职员来说,底层的交互过程是非常复杂的,ASP.NET则将交互的处理过程进行了抽象化,这样使得开发职员可以直接建立表层的客户端回调,而无需考虑底层的操纵是怎么实现的。
下面的实例中,页面中放置了一个文本框,一个提交按钮和一个标签。文本框是用来接受用户的输入资讯,在单击提交按钮后将把文本框中输入的资讯在标签上进行实时的显露。留意,在输入资讯后单击提交按钮时,并无像以前传统的提交方法那样重新对页面进行构建和刷新。图1-1为该实例的效果图。
创立基础的页面
依照上图的布局在工具栏的"标准"标签中拖拽出一个TextBox组件,一个Label组件到主窗体上。然后在"HTML"标签中拖拽出一个InputButton的HTML按钮,留意,该按钮不是我们经常使用的服务器端组件,而是一个HTML元素。在按钮中添加一个onclick事件,点击该按钮这将向服务器端发出回调请求,这个onclick事件的具体实现细节将在以后的过程中加以说明。得到的初始页面代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="CallBackExample.aspx.cs" Inherits="CallBackExample" %>
<html xmlns="http://www.xxx.cn/1999/xhtml">
<head runat="server">
<title>客户端回调</title>
</head>
<body>
<form runat="server">
<div>
请输入资讯:<asp:TextBox runat="server"></asp:TextBox>
<input type="button" value="提交" />
<br />
<asp:Label runat="server"></asp:Label>
</div>
</form>
</body>
</html>
执行回调
为了实现客户端回调,你的页面逻辑代码中必须实现一个ICallbackEventHandler接口。代码如下:
public partial class CallBackExample : System.Web.UI.Page,
System.Web.UI.ICallbackEventHandler
{… …}
ICallbackEventHandler接口定义了两个方法,RaiseCallbackEvent()从浏览器接受一个字符串作为事件参数,即该方法接受客户端JavaScript使传送的参数,留意它是首先触发的。接下来触发的就是GetCallbackResult()方法,它将所得到的成果传回给客户真个JavaScript,JavaScript再将成果更新到页面。
本例中的RaiseCallbackEvent()中的参数为我们在文本框的输入资讯。为了说明它是从服务器返回的,我们加了一些说明性的文字。然后用GetCallbackResult()方法中将成果传回到客户端。完整的页面逻辑代码如下:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class CallBackExample : System.Web.UI.Page,
System.Web.UI.ICallbackEventHandler
{
//定义一个字符串,回调的成果资讯将保管在该字符串中
private string result;
//引发回调事件处理
public void RaiseCallbackEvent(string eventArgument)
{
//"eventArgument"为从客户真个JavaScript传送过来的参数
result = "从服务器端返回的内容:" + eventArgument;
}
//回传回调成果
public string GetCallbackResult()
{
return result;
}
} 编写客户端脚本
客户端脚本重如果用来在服务器端和客户端中间进行资讯的交互,就拿本例来说,我们在前面的页面逻辑代码中使用了一个名为eventArgument参数,这是怎么实现参数的传送的呢?我们将在后面的章节进行商讨,现在在页面中添加如下的JavaScript函数代码
function CallServer(inputcontrol,context)
{
//回调还无处理完整时其预先加载的显露值
context.innerHTML = "加载中......";
//为你在文本框中输入的资讯,并且arg在这里就是将其值传送到
//RaiseCallbackEvent(String eventArgument)方法对应的eventArgument中
arg = inputcontrol.value;
//猎取一个对客户端函数的引用;调用该函数时,将启动一个对服务器端事件的客户端回调。
<%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context")%>;
}
我们在上述的JavaScript函数代码引用了一个ClientScript.GetCallbackEventReference(……)方法,该方法实现的是什么功效呢?下面是摘自MSDN2上的对ClientScript.GetCallbackEventReference(……)的具体说明。
public string GetCallbackEventReference (Control control,string argument,string clientCallback,string context)
参数:
参数作用control处理客户端回调的服务器 Control。该组件必须实现 ICallbackEventHandler 接口并提供 RaiseCallbackEvent 方法。 argument 从客户端脚本传送一个参数到服务器真个RaiseCallbackEvent 方法。 clientCallback 一个客户端事件处理程序的名称,该处理程序接受服务器端事件返回的成果。context启动回调之前在客户真个客户端脚本资讯。脚本的成果传回给客户端事件处理程序。 返回值调用客户端回调的客户端函数的名称。
下面是ClientScriptManager.GetCallbackEventReference 方法的重载列表
名称说明ClientScriptManager.GetCallbackEventReference (Control, String, String, String)猎取一个对客户端函数的引用;调用该函数时,将启动一个对服务器端事件的客户端回调。此重载方法的客户端函数包含指定的组件、参数、客户端脚本和上下文。ClientScriptManager.GetCallbackEventReference (Control, String, String, String, Boolean)猎取一个对客户端函数的引用;调用该函数时,将启动一个对服务器端事件的客户端回调。此重载方法的客户端函数包含指定的组件、参数、客户端脚本、上下文和布尔值。ClientScriptManager.GetCallbackEventReference (Control, String, String, String, String, Boolean)猎取一个对客户端函数的引用;调用该函数时,将启动一个对服务器端事件的客户端回调。此重载方法的客户端函数包含指定的组件、参数、客户端脚本、上下文、错误处理程序和布尔值。ClientScriptManager.GetCallbackEventReference (String, String, String, String, String, Boolean)猎取一个对客户端函数的引用;调用该函数时,将启动一个对服务器端事件的客户端回调。此重载方法的客户端函数包含指定的目标、参数、客户端脚本、上下文、错误处理程序和布尔值。 我们就整个程序作个系统的说明,并且列出前台的页面代码和后台的逻辑代码,这样可以使得你对程序有个直看的懂得。
后台代码 CallBackExample.aspx.cs
代码说明:
若要从客户端胜利运行服务器代码,而不执行回发,必须在服务器页代码中实现合适的接口。为此我们在第12行代码中对 ICallbackEventHandler 接口进行声明。第15和19行创立了两个服务器真个代码回调方法。第15行的"RaiseCallbackEvent()"方法中的"eventArgument"字符串参数是来什么处所呢?转到前台页面的第10行代码,arg就相当于传送给"RaiseCallbackEvent()"方法的实参。第19行的"GetCallbackResult()"方法则将通过"RaiseCallbackEvent()"方法得到的成果返回给客户端,即成果"result"终极被传送到前台页面的第15代码所示的"ReceiveServerData()"方法的"result"参数中。
前台代码 CallBackExample.aspx
代码说明:
为了向服务器页发送回协调接受成果这两个功效,我们在前台页面中定义了2个客户端脚本函数。第7行所示的"CallServer()"函数实现的就是发送回调的功效,留意发送回调的函数实际是在服务器端实现的,这是由于真正实现发送回调的是第11行的"ClientScript.GetCallbackEventReference()"方法,而"CallServer()"函数只是对"ClientScript.GetCallbackEventReference()"方法的引用,并提供一些必要的参数。
现在我们来具体讲解下这些客户端函数的具体实现细节,我们通过单击页面第25和26行所声明的按钮后,将触发OnClick事件。
在"CallServer()"中将文本框和标签作为参数传送到第7行相应的JavaScript函数后,"inputcontrol"和"context"就犹如成为文本框和标签组件形参数。第9行代码表示无接受到回调成果前"context"将显露一个"加载中……"的资讯,直到回调结束后才用第17行的代码将回调的成果用"context"重新进行显露。第10行代码表示将文本框的输入值舍予"arg",并且"arg"在第12行代码的ClientScript.GetCallbackEventReference()方法中作为对应的第2个参数。第一个参数用"this"表示对本页面的引用,由于ClientScript.GetCallbackEventReference()方法也是在CallBackExample.aspx实现的。第三个参数表示接受回调成果的客户端函数,它在这和第15行代码所实现的ReceiveServerData()函数相匹配(留意函数名称必须是一致的,否则会导致出错),回调的成果将通过"context"进行显露。第四个参数"context"用于从服务器端返回的上下文,由于ClientScript.GetCallbackEventReference()方法是在服务器端执行的,在该方法中底本传送的"context"内容为一个"加载中……"的资讯,回调返回后"context"在第17行中被重新进行改写,如果无对上下文的引用的话,你可以将该参数设置为"null"。
读取数据库资讯的客户端回调程序
本程序是一个实现读取Northwind数据库的Emlpoyees资讯,为此你必须先保证Northwind数据库存在。下图是Emlpoyees表的内容。
在文本框输入要搜索的用户名后,接着点击"回调"按钮就会产生客户端回调。这是搜索到用户的显露成果
用户不存在的显露资讯:
后台代码:ClientCallbacksSimple.aspx.cs
01 using System;
02 using System.Data;
03 using System.Configuration;
04 using System.Collections;
05 using System.Web;
06 using System.Web.Security;
07 using System.Web.UI;
08 using System.Web.UI.WebControls;
09 using System.Web.UI.WebControls.WebParts;
10 using System.Web.UI.HtmlControls;
11 using System.Data.SqlClient;
12 public partial class ClientCallbacksSimple : System.Web.UI.Page, 13
13 System.Web.UI.ICallbackEventHandler
14 {
15 protected string strUserInfo; //保管读取的用户资讯
16 //引发回调事件
17 public void RaiseCallbackEvent(string txtFirstName)
18 {
19 if (txtFirstName != null)
20 {
21 SqlConnection conn = new SqlConnection("data source=localhost;initial
22 catalog=Northwind;integrated security=SSPI");
23 conn.Open();
24 SqlCommand cmd = new SqlCommand("select EmployeeID,FirstName,City,Address 25
25 from Employees where FirstName=@FirstName", conn);
26 cmd.Parameters.Add("@FirstName", SqlDbType.NVarChar, 10).Value = txtFirstName;
27 SqlDataReader dr = cmd.ExecuteReader();
28 if (dr.Read())
29 {
30 strUserInfo = "员工代号:" + dr["EmployeeID"] + "/r/n";
31 strUserInfo += "姓名:" + dr["FirstName"] + "/r/n";
32 strUserInfo += "居住城市:" + dr["City"] + "/r/n";
33 strUserInfo += "地址:" + dr["Address"].ToString().Replace("/r/n","")+ "/r/n";
34 strUserInfo += "服务器查询时间:" + DateTime.Now.ToLongTimeString();
35 }
36 else
37 {
38 if (String.IsNullOrEmpty(txtFirstName))
39 {
40 strUserInfo = "请输入姓名";
41 }
42 else
43 {
44 strUserInfo = "查无此人";
45 }
46 }
47 cmd.Dispose();
48 dr.Dispose();
49 conn.Dispose();
50 }
51 }
52 //回传回调成果
53 public string GetCallbackResult()
54 {
55 return strUserInfo; //回传员工的基础资讯
56 }
57 }
代码说明:在RaiseCallbackEvent()方法中,传送了一个从前台页面文本框的输入数据作为其参数,即所要从数据库查询的用户名。第28-34行代码的功效为读取用户的具体资讯,并且将用户资讯保管在一个字符串strUserInfo中。如果搜索不到相应的用户,则返回一些出错资讯,见代码36-45。GetCallbackResult()方法回发回调成果,即保管用户资讯的字符串。
前台代码:ClientCallbacksSimple.aspx
01 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="ClientCallbacksSimple.aspx.cs"
02 Inherits="ClientCallbacksSimple" %>
03 <html xmlns="http://www.xxx.cn/1999/xhtml" >
04 <head runat="server">
05 <title>读取数据库资讯的客户端回调程序</title>
06 <script type="text/JavaScript">
07 function OnCallback(strUserInfo,context)
08 {
09 Results.innerText = strUserInfo;
10 }
11 </script>
12 </head>
13 <body>
14 <form runat="server">
15 <div>
16 姓名:<input type="text" />
17 <input type="button" value="回调" document.form1.txtUserName.value",
19 "OnCallback",null) %>" />
20 <br />
21 <div ></div>
22 </div>
23 </form>
24 </body>
25 </html>
代码说明:这个程序与第一个程序的最大不同就是前台页面上有些细小的区别。如代码17-19所示,我们将发送回调的ClientScript.GetCallbackEventReference()方法直接写在了按钮的单击事件中,这也是一种可行且简捷的方法。ClientScript.GetCallbackEventReference()方法的3个参数为"OnCallback",表示回调结束后将回调成果返回给客户真个OnCallback()脚本函数,在此回调成果strUserInfo将作为该函数的一个参数在页面进行显露,如代码9所示。由于我们在此无用到上下文的接洽,所以ClientScript.GetCallbackEventReference()方法的4个参数为"null",但是OnCallback()脚本函数还是要保存该"context"参数,由于这是接受回调成果的客户端函数的固定格式。
小结:
留意全部的异步技术如本文所探讨的Callback客户端回调,以及微软新推出的Atlas框架,都不再使用传统的Postback。因此客户端在出现由服务器端返回的数据时,浏览器下方将看不到一闪而过的绿色状况条,并且异步过程只传送和接受少量的数据,而非Postback过程中传送的整个ViewState状况,因此程序在执行性能上有了较大的进步。希看读者耐心懂得和练习上述的两个实例,只有通过自己的实践能力懂得客户端回调的精华。