前言
ajax可以说是今天互联网最流行的词语,然而其根本就是客户端异步的调用服务器端,最终返回需要的东西。目前我们都会用asp.netajax、ajax.net或者是纯xmlhttp式的异步调用,其实asp.net2.0内部也提供了一种异步调用的方式,那就是Callback机制(相对于postback来讲)。
ICallbackEventHandler接口
Callback机制用ICallbackEventHandler接口来实现,该接口定义了两个方法。
//返回服务器执行的结果给客户端
public string GetCallbackResult()
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
//throw new Exception("The method or operation is not implemented.");return rValue;
}
![](/Images/OutliningIndicators/None.gif)
//callback被触发时的处理方法
public void RaiseCallbackEvent(string eventArgument)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
//throw new Exception("The method or operation is not implemented.");
}
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
ClientScript对象
然后就是结合ClientScript对象的一系列方法实现客户端callback服务器端的引用,客户端脚本注册等等了,即是说用客户端方法触发了服务器端的事件。在做了一系列事件后就把结果返回给客户端。
//获得客户端要触发服务器的函数的引用,这样一来该客户端函数就可以异步的触发服务器端的事件并做响应处理了,所以要想用Callback,这个是必须要用的方法之一
GetCallbackEventReference(Control control, string argument, string clientCallback, string context);
//将一段脚本(js)注册(添加)到客户端去,这个也是经常用到的方法
RegisterClientScriptBlock(Type type, string key, string script);
![](/Images/OutliningIndicators/None.gif)
过程实例分析
要用到的东西大概这么多,而整个异步调用的过程是:
1,在aspx中放一个js函数(用来触发服务器端事件),使之有处理服务器传回数据的能力,这一步也可以在aspx.cs生成脚本块并注册到aspx中去;
2,在aspx.cs里面先用GetCallbackEventReference生成一个步骤1中函数的引用,这一步使之有了触发服务器事件的能力,并指定了参数和上下文;
3,再在aspx.cs里面放一个触发步骤1中函数的函数(用来传递一些参数和上下文进来);
4,在aspx中适当的位置触发步骤3中的函数并传响应参数和上下文进来。
这就是整个过程,干说很累,搞个例子:
aspx文件如下:
<!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 runat="server">
<title>Client PostBack Demo</title> <link href="Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<div>Enter Category ID: <input type="text" id="txtCategoryID" name="txtCategoryID" /> <input type="button" value="Submit" onclick="GetProductsByCategoryID()" /><br />
<br />
<br />
<div id="MyDiv" runat="server">
</div>
<asp:GridView ID="myGridView" CssClass="GridViewBackGround" runat="server" />
</div>
</form>
</body>
</html>
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
<script language ="javascript" type="text/javascript">![](https://www.cnblogs.com/Images/dot.gif)
function GetProductsByCategoryID()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
{
// txtCategoryID is the textbox
categoryID = document.getElementById("txtCategoryID").value;
CallServer(categoryID,'');
}
function ReceiveServerData(rValue)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
{
document.getElementById("myDiv").innerHTML = rValue;
}
</script>
其中的按钮的click事件触发了GetProductsByCategoryID()函数,GetProductsByCategoryID()又调用了“CallServer(categoryID,'')”(步骤3中的函数),这时传入了两个参数一个进来。下面CallServer就会调用要触发服务器事件的客户端函数(名称是ReceiveServerData)的引用[GetCallbackEventReference(this, "arg", "ReceiveServerData", "context")返回]。
aspx.cs文件如下:
protected void Page_Load(object sender, EventArgs e)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
string sbReference = ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");
string cbScript = String.Empty;
![](/Images/OutliningIndicators/InBlock.gif)
// check if the script is already registered or not
if (!ClientScript.IsClientScriptBlockRegistered("CallServer"))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
cbScript = @" function CallServer(arg,context) { " + sbReference + "}";
ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", cbScript, true);
}
}
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
这时就会触发一个事件,响应方法是RaiseCallbackEvent(string eventArgument),这个string型参数就是刚才GetCallbackEventReference(this, "arg", "ReceiveServerData", "context")中指定的arg。
当上面的方法执行完毕后就会触发另一个事件,响应方法是string GetCallbackResult(),它会返回一个string给触发触发服务器事件的客户端函数ReceiveServerData(),最终将要更新的客户端做响应改变。
结论
异步调用服务器端技术被人封装了很多了,微软也不例外,除了asp.netajax外,在asp.net中也内置了Callback机制来实现异步调用,其实其底层还是xmlhttp的封装,不过asp.netajax的功能和控件要强大的多,相比callback就“轻量”的多了。