MS的解释是:回调允许控件或页以不需要回发整个页的方式执行对服务器的带外回调。这意味着您的自定义控件将不会导致客户端浏览器等待整个页的回发,并且自定义控件能够启用丰富的 UI 功能。您可开发自定义控件,轻松组合如 Web 资源及客户端脚本管理,以使用回调基础结构。
要使用回调,必须做到以下条件:
在自定义控件中创建一个具有给定签名的服务器端回调事件 (ICallbackEventHandler.PrepareCallbackEvent),它在有参数传入方法时起作用。应调用开发人员在扩展您的自定义控件时可重写的方法;
创建生成回调结果的服务器端方法 ICallbackEventHandler.RenderCallbackResult。应调用开发人员在扩展您的自定义控件时可重写的方法。返回结果将传递给由您的自定义控件定义的客户端脚本;
创建管理返回调用或错误的客户端脚本。这将通过您的自定义控件生成;
在您的自定义控件中使用与客户端事件挂钩的回调事件引用。
废话不多说,直接开干!
创建一个新的页面,选用的是将代码放在单独的文件中(Code Behind)。
本来以前可以直接COPY以前Beta2下的例子就可以,结果把代码粘贴过来,直接编译,出错。Aspx.CS文件代码如下:
public partial class ClientCallback : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
{
protected void Page_Load(object sender, EventArgs e)
{
ArrayList values = new ArrayList();
values.Add("Item 1");
values.Add("Item 2");
values.Add("Item 3");
values.Add("Item 4");
values.Add("Item 5");
values.Add("Item 6");
ListBox1.DataSource = values;
ListBox1.DataBind();
String cbReference = Page.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");
String callbackScript;
callbackScript = "function CallTheServer(arg, context)" +
"{ " + cbReference + "} ;";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"CallTheServer", callbackScript, true);
}
public String RaiseCallbackEvent(String eventArgument)
{
return "Congratulations!You select " + eventArgument;
}
}
第一个错误居然是span的不能用ID的大写字母,晕!只有改成小写。
下面的两个错误就搞不懂了,查了一下MSDN,把里面例子的代码copy过来一看,和以前的Beta2代码一样,还是出错。再看了一下ASP.NET快速入门,居然发现里面的代码里面有一个错误,在一个返回string的方法里面写着return = "Some data";彻底晕。看来MS这次的MSDN和入门文档有问题,不知道这算不算bug咧,嘿嘿~~~~~
看来只有自己研究了,看了一下ICallbackEventHandler,发现里面除了RaiseCallbackEvent,还有一个GetCallbackResult,会不会是这个方法呢? 结果发现如果只写GetCallbackResult(),编译的时候出错,如图:
必须要写成ICallbackEventHandler.GetCallbackResult()!!
在GetCallbackResult里面写了个return "hello",先调试通过了再说。
再编译,还是出错,如图:
看了一下MSDN,发现RaiseCallbackEvent现在已经成了一个void类型,看来确实和Beta2变化比较大。算了,暂时不用这个,改成void。再编译,终于没有出错了,汗!(当然,还是得用ICallbackEventHandler.RaiseCallbackEvent)。
访问一下页面,还算好,一切正常,呵呵。如图:
第一次访问:
点击后:
刷新页面,没有出现那个确认提交的提示框,达到回调的目的!
修改cs文件,一个简单的回调页面就完成了。
通过这个页面,可以发现回调的时候,RaiseCallbackEvent是处理提交上来的信息,而GetCallbackResult则是取得结果的方法,这和beta2里面使用回调是不一样的。也说明了MSDN的编写并不完美,可能是不同的开发团队之间配合没跟上,希望以后的补丁能修改过来。
完整的代码如下:
页面
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ClientCallback.aspx.cs" Inherits="ClientCallback" %>
<!DOCTYPE html PUBLIC "-//W 3C //DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Test</title>
<script type="text/javascript">
function test()
{
var lb = document.forms[0].ListBox1;
var con = lb.options[lb.selectedIndex].text;
CallTheServer(con, "");
}
function ReceiveServerData(rValue)
{
Results.innerText = rValue;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ListBox ID="ListBox1" runat="server" Height="95px" Width="115px"></asp:ListBox>
<br />
<br />
<button οnclick="test()">Get Message</button>
<br />
<br />
Server Return IS:
<br />
<span id="Results"></span>
<br />
</div>
</form>
</body>
</html>
CS文件:
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 ClientCallback : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
{
protected void Page_Load(object sender, EventArgs e)
{
ArrayList values = new ArrayList();
values.Add("Item 1");
values.Add("Item 2");
values.Add("Item 3");
values.Add("Item 4");
values.Add("Item 5");
values.Add("Item 6");
ListBox1.DataSource = values;
ListBox1.DataBind();
String cbReference = Page.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");
String callbackScript;
callbackScript = "function CallTheServer(arg, context)" +
"{ " + cbReference + "} ;";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"CallTheServer", callbackScript, true);
}
string result;
void ICallbackEventHandler.RaiseCallbackEvent(String eventArgument)
{
result = "Hello! You select " +eventArgument +". The Server Time is "+ DateTime.Now.ToString();
}
string ICallbackEventHandler.GetCallbackResult()
{
return result;
}
}