Callback 原来很简单!

    远在自己没有接触dot Net2之前,就看过不少牛人的关于callback的文章,当然分析原理解析内幕都很透彻。不过给我留下的感觉却是callback使用比较晦涩麻烦,既然有现成的Ajax框架使用,我就不考虑了。
    原来我一直使用Ajax pro框架用起来还是比较顺畅的,可是自从Atlas出来了几个CTP版本,我终于有点忍不住了,最可恨的是那几个老外一直在哪里叫嚷,Atlas已经可以用于生产了。咱一想这毕竟是微软的嫡系部队啊,要不用用。谁知到这一用就上了贼船了!且不说现在的asp.net 2 ajax 1.0 beta 已经面目全非了。当然微软的东西一贯是博大精神的,可是bug也不少,尤其麻烦的是,我发现兼容性也有问题。咱不要求和什么Fixfox之类的兼容可是和同样6.0sp1版本的windows98,2000下面的IE那得全兼容吧,可事实确并非如此!
    我的程序原来是这样设计的,根据用户权限生成菜单,每个菜单都又一个GUID,用户点击菜单后在客户端调用服务器端的程序,设置参数环境然后返回实际URL,再由客户端导航到该URL。原来用AJAX pro实现很简单没有问题。迁移到Atlas之后,复杂了点儿,使用了Webservice,在客户端的脚本中调用WebService。开发调试的时候没有发现问题,可是到了客户那里就不行了。客户的系统有xp,2000,98,只有xp的系统才行!开始认为是浏览器版本的问题,可是全部升级到IE6+sp1后问题依旧。98下是偶尔可以,2000下面是根本不行,出问题的就是这一行放在页面最后的javascript脚本:
Sys.Application.load.add(doCmd); 

看错误信息就是提示对象为空或找不到。我分析好像是Atlas的客户端脚本没有下载或立即执行的语句没有执行。到网上搜了搜,在CSDN上有人提类似的问题,没有人给出解决方案。试着封装了一个函数然后加个延时再调用这一句,依然不行。最后只好放弃了。难道要用回Ajax Pro?肯定不行,Atlas别的方面还不错,而且程序里面不少地方使用了Update Panel,这玩意还是不错的。最后锁定了Callback调用,认真地研究了下,发现这个远没有想象的复杂,比Ajax pro用起来都简单,最简单的就这么几步。

页面级使用callback的方法:
1,页面类继承ICallbackEventHandler接口
2,实现ICallbackEventH#region ICallbackEventHandler 成员

        public string GetCallbackResult()
        {
            
return ExecCommand(cmdID);
        }

        public 
void RaiseCallbackEvent(string eventArgument)
        {
            cmdID 
= eventArgument;
        }

        #endregionandler接口
就这么简单,其中cmdID是一个页面类的变量,ExecCommand函数用于从数据库中取得URL

3,获取客户端调用脚本,实际上就是由.Net生成对自己生成的WebForm_DoCallback()的函数的调用:
this.ClientScript.GetCallbackEventReference(this"'" + cmdId + "'""OnExecResult", string.Empty, "OnExecError"true));
这个函数实际返回的就是一个可以注册到脚本中的字符串,形如,WebForm_DoCallback('
thePage', 'cmdid', OnExecResult, '', OnExecError, true); 我所要做得就是把这个加入到我的脚本中:
private void RegisterJs(string cmdid)
  {
   StringBuilder exec = new StringBuilder();
   exec.Append("<script>");
   exec.Append("function OnExecResult(result)");
   exec.Append("{self.navigate(result);}");
   exec.Append("function OnExecError(result)");
   exec.Append("{alert('error:'+result);}");
   exec.Append("function doCmd(){");
   exec.Append(this.ClientScript.GetCallbackEventReference(this, "'" + cmdid + "'", "OnExecResult", string.Empty, "OnExecError", true));
   exec.Append("}");
   exec.Append("doCmd();");
   exec.Append("</script>");
   this.ClientScript.RegisterStartupScript(this.GetType(), "exec", exec.ToString());
  }
    经过测试问题解决了!
    当然,使用callback后也有缺点。其一,相当于整个页面做了Postback的工作量,不过对于简单的页面不应有什么性能的问题,我这回调页面就一个HTML控件都没有,用起来那是相当的快!其二,那个貌似先进的Web Service用不到了,有点儿遗憾哈^_^。
    看来Callback还是很好用的,以后要多用。另,文中所说的问题没有在asp.net 2 ajax 1.0 beta 中试验,据说这个版本客户端库小了很多,也去掉了好多功能。不过我也不想试了,那位大侠试试,有结果请别忘了在百忙中通知我:)。
posted @ 2006-11-04 01:14  柒零壹  阅读(1702)  评论(3编辑  收藏  举报