转自:http://blog.youkuaiyun.com/lee576/archive/2008/01/15/2045393.aspx
作者:NasirAliKhan
译者:veryhappy(wx.net)
客户端回调是ASP.NET中一个非常好的特性,可以从客户端的JavaScript通过XmlHttp方式调用服务器端的代码,一般的叫Ajax。在这篇文章中我们将首先讨论客户端回调然后比较它与Ajax的益处。(译者:文章中采用的方法是完全ASP.NET 2.0中提供的,无需要使用其它的Ajax框架或是自己动手写XmlHttp请求这两种方式来实现)。
在ASP.NET 1.1中使用Ajax是相当繁重的一项工作。首先你需要拷贝Ajax.dll到站点的Bin目录中,然后在Web.config中注册HttpHandler,事情并没有结束,因为在你需要使用异步调用的页面都需要注册,调用AJAXUtility.RegisterForAJAXType (this.GetType ()),这以后才可以开始写实际需要的客户端和服务器端代码。
在ASP.NET 2.0中带来了一套简单方法来处理注册httphandler,Page类型等,完成客户端回调。以下的文章内容将讨论关于它详细的内容。
ASP.NET提供了一个新的接口ICallBackEventHandler,为了实现客户端回调Page类必须来实现这个接口。它有两种方法:
- RaiseCallbackEvent:处理以控件为目标的回调事件,这个方法将在客户端脚本调用服务器代码时来执行;
- GetCallbackResult:返回以控件为目标的回调事件的结果,结果通常被RaiseCallBackEvent 和存储在一些类中成员变量返回;
下面就是客户端回调的实例
先来看一个非常基本的回调实例。实现客户端按钮调用服务器端代码,然后从服务器返回一个简单的文本信息到客户端的TextBox中。
必须集成实现ICallbackEventHandler接口
public partial class _Default :
System.Web.UI.Page, ICallbackEventHandler
{
string callbackResult;
protected void Page_Load(object sender, EventArgs e)
{
// 稍后讨论这里
}
public void RaiseCallbackEvent(string eventArgument)
{
// 服务器端操作
callbackResult = "DotNET Rocks!";
}
public string GetCallbackResult()
{
return callbackResult;
}
}
上面的代码简单的在RaiseCallbackEvent中执行了一个操作并且把它保存到了结果callbackresult变量中,这个结果将被GetCallbackResult方法返回。下一步在客户端增加一些JavaScript脚本来触发这个回调。
<script type="text/javascript">
function GetMessageFromServer()
{
UseCallBack();
}
function JSCallback(TextBox1, context)
{
// 当回调结束后将执行这里的方法,把从服务器端获取的值进行客户端操作
document.forms[0].TextBox1.value = TextBox1;
}
</script>
“GetMessageFromServer”将调用UseCallback来触发服务器端代码,这个“UseCallback”方法是动态的方法,它将从服务器端后台代码处生成。“JSCallback”方法将在服务器端代码调用完成以后在回调执行。在这里我们是返回了一个字符串。
<input type="button" id="Button1" runat="server" value="Get Message" onclick="GetMessageFromServer()"/>
现在开始最后也是最重要的步骤,负责从Javascript发送XmHttp来调用服务器端的方法,通常的以下代码将放到Page_Load事件中执行
protected void Page_Load(object sender, EventArgs e)
{
// 获得客户端回调方法JSCallback的引用
string cbref = Page.ClientScript.GetCallbackEventReference(this, "arg", "JSCallback", "context");
// 生成一个JavaScript脚本来触发回调
string cbScr = string.Format("function UseCallBack(arg, context) {{ {0}; }} ", cbref);
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "UseCallBack", cbScr, true);
}
上面的C#代码在运行时,将在页面生成如下的JavaScript代码:
function UseCallBack(arg, context)
{
WebForm_DoCallback('__Page',arg,JSCallback,context,null,false);
}
实际上通过XmlHttp,最终从服务器端返回结果回调客户端方法。所以在服务器端执行完成之后框架将通知JavaScript方法告知服务器已经执行完毕,例子中将调用function JSCallback(TextBox1, context).
深入回调
你也许会感到奇怪就是XmlHttp对象在哪里,框架如何回调。那么在最后生成的Page页中你会发现一段有趣的脚本:
<script src="/<AppName>/WebResource.axd?d=v…&t=63…0" type="text/javascript"></script>
如果你在浏览器中打开这个URL打开这段脚本,你会发现关于类库功能的完整定义和负责服务器调用和客户端通知的对象。
另外,在前面的代码Page类的一个属性ClientScript来表示ClientScriptManager的实例,它包含了涉及到的大多数客户端方法。GetCallbackEventReference用来返回客户端方法的一个引用。通过这个方法来从客户端调用服务器端事件。
客户端回调中Page的生命周期
客户端回调的一个特点,当服务器端回调时,Page是装载到内存并且执行了Page生命周期中通常的方法,像Page_Init, Page_Load等。这点是区别与Ajax的,因为Ajax的页面不会装载到内存中,所以你也就不能访问ViewState,页面上的控件。
可是在客户端回调的页面周期的部分事件,像Pre_Render,Render不会触发,其实这也是符合逻辑的,因为我们并不想让页面刷新。下面的图来描述Page的生命周期。
通常ASP.NET 2.0中Page的生命周期
客户端回调Page生命周期
带参数的客户端回调
你可以传递参数到服务器端代码虽然只是一个参数,传递参数的方法非常简单。如果需要也可以在动态生成方法的时候从服务器端生成参数。
function GetMessageFromServer()
{
var parameter = “some paramter”;
UseCallBack(parameter, "");
}
public void RaiseCallbackEvent(string eventArgument)
{
// 处理eventargument参数
callbackResult = “some result”;
}
客户端回调与AJAX的比较
下面是一些客户端回调方法相比Ajax的优点
- 使用不同的Ajax框架会带来很多不同的实现手法,因为它并没有标准化;ASP.NET 2.0中的客户端回调是一种统一的方式。
- 这样的客户端回调方式意味着可以访问页面的ViewState和Form控件。
- 不需要注册HttpHandlers在配置文件中。
- 利用这样的方式,开发人员可以不必写过多的JavaScript代码,调用Page.ClientScript.GetCallbackEventReference可以动态的生成减少错误。
总结
客户端回调是ASP.NET 2.0中非常棒的一个新特性,它允许用过XmlHttp方式进行服务器端的异步调用,也就是一般我们讲的Ajax。客户端回调脚本拥有某些Ajax并不具备的好特点,像访问页面的ViewState和Form控件。
原文引自:http://www.codeproject.com/useritems/ClientCallback.asp
实例下载:http://www.codeproject.com/useritems/ClientCallback/ClientCallback_src.zip