|
 |
栏目导栏 |
|
| |
|
|
|
|
 |
资料搜索 |
|
| |
|
|
|
|
 |
热门文章 |
|
| |
|
|
|
|
 |
最新文章 |
|
| |
|
|
|
| |
| |
|
|
|
| |
| Asp.net Ajax 1.0 异步回调时,服务器端Render原理 |
|
首冼回顾一下 HPkLinux联盟 Page页的生命周期 HPkLinux联盟 HPkLinux联盟 PreInit HPkLinux联盟 Init HPkLinux联盟 InitComplete HPkLinux联盟 LoadState HPkLinux联盟 ProcessPostData HPkLinux联盟 PreLoad HPkLinux联盟 Load HPkLinux联盟 LoadComplete HPkLinux联盟 PreRender HPkLinux联盟 PrepareCallback //如果有回调 HPkLinux联盟 PreRenderComplete HPkLinux联盟 SaveState HPkLinux联盟 SaveStateComplete HPkLinux联盟 Render HPkLinux联盟 HPkLinux联盟 不论是Asp.net请求,还是Ajax请求,都要执行上面的页生命周期, HPkLinux联盟 HPkLinux联盟 在Page页最后会调用Page.RenderControl()呈现Page所有子控件 HPkLinux联盟 HPkLinux联盟 流程如下 HPkLinux联盟 HPkLinux联盟 Page.RenderControl HPkLinux联盟 Control.RenderControl() HPkLinux联盟 Control.RenderControl(writer,this.Adapter) HPkLinux联盟 Control.RenderControlInternal() HPkLinux联盟 Control.Render() //此时Page.Render()将其重写 HPkLinux联盟 Control.RenderChildren() HPkLinux联盟 Control.RenderControlInternal() HPkLinux联盟 HPkLinux联盟 现在关键所在 HPkLinux联盟 Control.RenderControlInternal()实现如下 HPkLinux联盟 如果不是Asp.net Ajax处理,肯定会执行foreach依次对所有的子控件进行遍历 HPkLinux联盟 HPkLinux联盟 internal void RenderChildrenInternal(HtmlTextWriter writer, ICollection children) HPkLinux联盟 { HPkLinux联盟 //正常情况如果不设置RareFields,进行默认的流程依次对所有子控件进行处理, HPkLinux联盟 //如果设置RareFields,意思就是以自定义的方式改写RenderChildren HPkLinux联盟 if ((this.RareFields != null) && (this.RareFields.RenderMethod != null)) //当您SetRenderMethodDelegate时,RareFieldsEnsured就有值啦 HPkLinux联盟 { HPkLinux联盟 writer.BeginRender(); HPkLinux联盟 HPkLinux联盟 //调用RenderMethod委托,Asp.net Ajax1.0在使用Control.SetRenderMethodDelegate时,对应的回调函数就是在此时处理的 HPkLinux联盟 this.RareFields.RenderMethod(writer, this); HPkLinux联盟 writer.EndRender(); HPkLinux联盟 } HPkLinux联盟 else if (children != null) HPkLinux联盟 { HPkLinux联盟 //如果不设置这个RareFieldsEnsured,会把Page里所有的控件呈现 HPkLinux联盟 //依次调用Control里所有子控件的RenderControl HPkLinux联盟 foreach (Control control in children) HPkLinux联盟 { HPkLinux联盟 control.RenderControl(writer); HPkLinux联盟 } HPkLinux联盟 } HPkLinux联盟 HPkLinux联盟 } HPkLinux联盟 HPkLinux联盟 以上是Asp.net 的Render处理 HPkLinux联盟 肯定有人要问上面的if是干吗的,这个可是微软流的接口呀,整个asp.net ajax全靠这个接口进行处理 HPkLinux联盟 HPkLinux联盟 在Asp.netAjax1.0上,你肯定要放一个ScriptManager吧 HPkLinux联盟 它也是Control的子类, HPkLinux联盟 在Page生命周期的OnPreRender时,它会调用 HPkLinux联盟 HPkLinux联盟 PageRequestManager.OnPreRender(); HPkLinux联盟 HPkLinux联盟 HPkLinux联盟 问题就在这,PageRequestManager.OnPreRender()实现如下 HPkLinux联盟 HPkLinux联盟 _owner.IPage.SetRenderMethodDelegate(RenderPageCallback); HPkLinux联盟 HPkLinux联盟 SetRenderMethodDelegate()方法是干什么用的 HPkLinux联盟 HPkLinux联盟 在Control中,当您调用了SetRenderMethodDelegate会给Control.RareFieldsEnsured设置值 HPkLinux联盟 public void SetRenderMethodDelegate(RenderMethod renderMethod) HPkLinux联盟 { HPkLinux联盟 //使用OccasionalFields.RareField HPkLinux联盟 this.RareFieldsEnsured.RenderMethod = renderMethod; HPkLinux联盟 this.Controls.SetCollectionReadOnly("Collection_readonly_Codeblocks"); HPkLinux联盟 } HPkLinux联盟 HPkLinux联盟 到这一切就清晰了,当您设置了RenderPageCallback,正常的Asp.net流程就不会再走了,所有的子控件就不会被Render HPkLinux联盟 在Asp.netAjax 1.0中使用 HPkLinux联盟 private void RenderPageCallback(HtmlTextWriter writer, Control pageControl) HPkLinux联盟 { HPkLinux联盟 ... HPkLinux联盟 //取出当前的HtmlForm HPkLinux联盟 IHtmlForm formControl = _owner.IPage.Form; HPkLinux联盟 HPkLinux联盟 //手动设置当FormControl.RenderControl时()回调方法 ,因为这个时候Page.Controls里有子控件不会被Render啦,怎么办 HPkLinux联盟 //手动处理一个呗 HPkLinux联盟 formControl.SetRenderMethodDelegate(RenderFormCallback); HPkLinux联盟 HPkLinux联盟 //同样,HtmlForm.RenderControl不会在Page.Controls里自动触发的 HPkLinux联盟 //这个时候您需要手动的RenderCtronl一下,这样才能调用RenderFormCallback HPkLinux联盟 formControl.RenderControl(formWriter); HPkLinux联盟 HPkLinux联盟 //生成客户端回调信息|asyncPostBackControlIDs HPkLinux联盟 EncodeString(writer, AsyncPostBackControlIDsToken, String.Empty, GetAsyncPostBackControlIDs(false)); HPkLinux联盟 //生成客户端回调信息 |postBackControlIDs HPkLinux联盟 EncodeString(writer, PostBackControlIDsToken, String.Empty, GetPostBackControlIDs(false)); HPkLinux联盟 //生成客户端回调信息 |updatePanelIDs|tUpdatePanel HPkLinux联盟 EncodeString(writer, UpdatePanelIDsToken, String.Empty, GetAllUpdatePanelIDs()); HPkLinux联盟 //生成客户端回调信息 |childUpdatePanelIDs HPkLinux联盟 EncodeString(writer, ChildUpdatePanelIDsToken, String.Empty, GetChildUpdatePanelIDs()); HPkLinux联盟 //生成客户端回调信息 |panelsToRefreshIDs HPkLinux联盟 EncodeString(writer, UpdatePanelsToRefreshToken, String.Empty, GetRefreshingUpdatePanelIDs()); HPkLinux联盟 //生成客户端回调信息 |asyncPostBackTimeout HPkLinux联盟 EncodeString(writer, AsyncPostBackTimeoutToken, String.Empty, _owner.AsyncPostBackTimeout.ToString(CultureInfo.InvariantCulture)); HPkLinux联盟 HPkLinux联盟 ........ HPkLinux联盟 HPkLinux联盟 } HPkLinux联盟 HPkLinux联盟 private void RenderFormCallback(HtmlTextWriter writer, Control containerControl) HPkLinux联盟 { HPkLinux联盟 .... HPkLinux联盟 //呈现所有的UpdatePanel HPkLinux联盟 if (_updatePanelsToRefresh != null) HPkLinux联盟 { HPkLinux联盟 foreach (UpdatePanel panel in _updatePanelsToRefresh) HPkLinux联盟 { HPkLinux联盟 if (panel.Visible) HPkLinux联盟 { HPkLinux联盟 panel.RenderControl(_updatePanelWriter); HPkLinux联盟 // 会生成如何的客户端回调信息 HPkLinux联盟 //169|updatePanel|UpdatePanel1|\r\n HPkLinux联盟 } HPkLinux联盟 } HPkLinux联盟 HPkLinux联盟 } HPkLinux联盟 ... HPkLinux联盟 //依次将页面上所有控件的RenderControl,写入dummyWriter HPkLinux联盟 foreach (Control control in containerControl.Controls) HPkLinux联盟 { HPkLinux联盟 control.RenderControl(dummyWriter); HPkLinux联盟 //生成一部分信息 HPkLinux联盟 <input type=\"submit\" name=\"Button1\" value=\"Button\" id=\"Button1\" />\r\n HPkLinux联盟 <input name=\"txt\" type=\"text\" value=\"wxy\" id=\"txt\" />\r\n HPkLinux联盟 } HPkLinux联盟 HPkLinux联盟 注意,在RenderFormCallback时,HttpRequest会手动的Flush()将上面的信息刷加IIS HPkLinux联盟 } HPkLinux联盟 HPkLinux联盟 至于Ctronl.Render时,是如何写入HtmlTextWriter,再写入HttpWriter, HPkLinux联盟 再写回HttpWorkRequest,最终刷回内核,或使用socket发送回服务器,不在本文讨论范围....... HPkLinux联盟 HPkLinux联盟 HPkLinux联盟 由上可见,Asp.net Ajax,必没有使用传统的HttpRequest.Filter来处理回发信息,而是使用了Asp.net 2.0内置的方式和回调的 HPkLinux联盟 HPkLinux联盟 HPkLinux联盟 Asp.net Ajax回调后呈现到客户端有二个部分,一部分是由RenderFormCallback生成的如下 HPkLinux联盟 HPkLinux联盟 RenderFormCallback部分会生成如下的客户端脚本 HPkLinux联盟 169|updatePanel|UpdatePanel1|\r\n HPkLinux联盟 HPkLinux联盟 <input type=\"submit\" name=\"Button1\" value=\"Button\" id=\"Button1\" />\r\n HPkLinux联盟 <input name=\"txt\" type=\"text\" value=\"wxy\" id=\"txt\" />\r\n HPkLinux联盟 HPkLinux联盟 一部分是RenderPageCallback生成的 HPkLinux联盟 HPkLinux联盟 52|hiddenField HPkLinux联盟 |__VIEWSTATE|/wEPDwUJNjg1NjA3NDcxZGRCX32AH2I/NEq+gCFrVrHPkLinux联盟 49kQDECw==|56 HPkLinux联盟 |hiddenField|__EVENTVALIDATION|/wEWAwKf344xAoznisYGApKGHPkLinux联盟 sMIJOfjKisKPYP0O2NXUpNjnA29hMlA=|0 HPkLinux联盟 |asyncPostBackControlIDs|||0|postBackControlIDs|||13|updatePanelIDs||HPkLinux联盟 tUpdatePanel1|0 HPkLinux联盟 |childUpdatePanelIDs|||12|panelsToRefreshIDs||UpdatePanel1|2|HPkLinux联盟 asyncPostBackTimeout||90|12 HPkLinux联盟 |formAction||Default.aspx|13|pageTitle||Untitled Page| HPkLinux联盟 HPkLinux联盟 HPkLinux联盟 在客户端的部分Sys.WebForm._onFormSubmitCompleted()会对所有的信息以Json type:type,id:id,content:content进行封装 HPkLinux联盟 取出UpdatePanel,设置其innerhtml
Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论 |
|
|
|
|
|