赛车

深度解析ASP.NET2.0中的Callback机制

2019-09-13 19:14:22来源:励志吧0次阅读

Serverside Callback Operation & Render

好了,那么接下来就让我们来看看在服务端,ASP.NET都为我们做了些什么。

首先,我们知道,当前的Page是必须实现ICallbackEventHandler这个接口的,也就是其包含的两个函数:string GetCallbackResult()和void RaiseCallbackEvent(eventArgument)。根据MSDN的文档,我们知道,在一个callback被post到服务端时,Page将会首先将post回来的form data绑定到当前页面的服务端web控件,接着判断本次post是callback还是postback,如果是postpost,那么自然是原来的那个机制;

如果是callback,则将回调用触发本次callback的控件(在本例中,我们在激发这个callback时,第一个参数指定的是this也就是当前的Page,那么这里当前的Page就是这个触发控件)的RaiseCallbackEvent(eventArgument),当然,eventArgument也将会正确的传过来,在这个函数的实现代码里我们可以对这个参数进行解析处理,并在某个地方,存储我们准备返回的数据,或者待处理的已经被解析出来的参数。

接着,系统将调用string GetCallbackResult(),在这个函数的实现代码中,我们可以直接返回我们在RaiseCallback函数中存储的准备返回的数据,或者根据待处理的已经被解析出来的参数处理这些参数,并返回结果。这个返回的字符串,自然将以脚本的形式被render回客户端。被返回的脚本细节如下(反编译Page.RenderCallback()的源码),我们可以看到,返回的结果除了我们需要的结果数据和相应的脚本,没有多余的数据,因此,callback的执行效率应该说还是不错的:

private void RenderCallback()

{

bool flag1 = !string.IsNullOrEmpty(this._requestValueCollection["__CALLBACKLOADSCRIPT"]);

try

{

string text1 = null;

if (flag1)

{

text1 = this._requestValueCollection["__CALLBACKINDEX"];

if (string.IsNullOrEmpty(text1))

{

throw new HttpException(SR.GetString("Page_CallBackInvalid"));

}

for (int num1 = 0; num1 < text1.Length; num1++)

{

if (!char.IsDigit(text1, num1))

{

throw new HttpException(SR.GetString("Page_CallBackInvalid"));

}

}

this.Response.Write("<script>parent.__pendingCallbacks[");

this.Response.Write(text1);

this.Response.Write("].xmlRequest.responseText=\"");

}

if (this._callbackControl != null)

{

string text2 = this._callbackControl.GetCallbackResult();

if (this.EnableEventValidation)

{

string text3 = this.ClientScript.GetEventValidationFieldValue();

this.Response.Write(text3.Length.ToString(CultureInfo.InvariantCulture));

this.Response.Write('|');

this.Response.Write(text3);

}

else

{

this.Response.Write('s');

}

this.Response.Write(flag1 ? Util.QuoteJScriptString(text2) : text2);

}

if (flag1)

{

this.Response.Write("\";parent.__pendingCallbacks[");

this.Response.Write(text1);

this.Response.Write("].xmlRequest.readyState=4;parent.WebForm_CallbackComplete();</script>");

}

}

catch (Exception exception1)

{

this.Response.Clear();

this.Response.Write('e');

if (this.Context.IsCustomErrorEnabled)

{

this.Response.Write(SR.GetString("Page_CallBackError"));

return;

}

this.Response.Write(flag1 ? Util.QuoteJScriptString(HttpUtility.HtmlEncode(exception1.Message)) :  HttpUtility.HtmlEncode(exception1.Message));

}

}

另外,才发现原来System.Web.UI.Utils这个类中有那么多有用的方便的函数如QuateJScriptString(),以前一直自己手写这样功能的函数呢~~真傻呀~~

Conclusion

至此,我们已经基本上清楚明白callback的前台幕后了。如果您对服务段的处理过程的细节还觉得不够,您也可以自行反编译Page对象,看看其实现代码的细节,还是很有意思的。

总体而言,我们发现,callback无论是兼容性(XMLHTTP或IFRAME我想大多数浏览器都支持吧),还是性能(没有返回不需要的数据),还是使用的便利性(因为ASP.NET帮我们绑定了页面上的当前的Web控件的数据,这就意味着我们可以在callback后的服务端,象postback时一样来写代码,也方便我们移植原来的postback的代码到callback方式的代码)都是非常优秀的。我们也完全可以扩展现有的控件,或者写我们自己的控件以支持这样的callback效果,并且,混合使用callback控件和原来的postback方式的控件也是非常可靠和容易的。这对我们升级原来的基于postback为主的代码,是非常有利的,如果用Atlas来做同样的代码升级和与postback方式的控件混合使用,我可以跟您说,会有很多问题。不信你自己可以试试。查看本文来源

治动脉硬化的药
心肌梗塞的后期治疗
小孩咳喘最有效的药
小儿便秘怎么治
分享到: