首先回顾一下
Page页的生命周期
Init
InitComplete
LoadState
ProcessPostData
PreLoad
Load
LoadComplete
PreRender
PrepareCallback //如果有回调
PreRenderComplete
SaveState
SaveStateComplete
Render
不论是Asp.net请求,还是Ajax请求,都要执行上面的页生命周期,在Page页最后会调用Page.RenderControl()呈现Page所有子控件流程如下
Control.RenderControl()
Control.RenderControl(writer,this.Adapter)
Control.RenderControlInternal()
Control.Render() //此时Page.Render()将其重写
Control.RenderChildren()
Control.RenderControlInternal()
现在关键所在
Control.RenderControlInternal()实现如下
如果不是Asp.net Ajax处理,肯定会执行foreach依次对所有的子控件进行遍历
以上是Asp.net 的Render处理
肯定有人要问上面的if是干吗的,这个可是微软流的接口呀,整个asp.net ajax全靠这个接口进行处理
在Asp.netAjax1.0上,你肯定要放一个ScriptManager吧
它也是Control的子类,
在Page生命周期的OnPreRender时,它会调用
PageRequestManager.OnPreRender();
问题就在这,PageRequestManager.OnPreRender()实现如下
_owner.IPage.SetRenderMethodDelegate(RenderPageCallback);
SetRenderMethodDelegate()方法是干什么用的
在Control中,当您调用了SetRenderMethodDelegate会给Control.RareFieldsEnsured设置值
到这一切就清晰了,当您设置了RenderPageCallback,正常的Asp.net流程就不会再走了,所有的子控件就不会被Render
在Asp.netAjax 1.0中使用
{
//呈现所有需要回发的的UpdatePanel
if (_updatePanelsToRefresh != null)
{
foreach (UpdatePanel panel in _updatePanelsToRefresh)
{
if (panel.Visible)
{
panel.RenderControl(_updatePanelWriter);
// 会生成如何的客户端回调信息
//169|updatePanel|UpdatePanel1|\r\n
<input type=\"submit\" name=\"Button1\" value=\"Button\" id=\"Button1\" />\r\n
<input name=\"txt\" type=\"text\" value=\"wxy\" id=\"txt\" />\r\n
}
}
}
//依次将页面上所有控件的RenderControl,写入dummyWriter
foreach (Control control in containerControl.Controls)
{
//将整个Page页上所有的控件写入垃圾器,
//此时,这些控件Render的信息不会发送到客户端
control.RenderControl(dummyWriter);
}
注意,在RenderFormCallback时,HttpRequest会手动的Flush()将上面的信息刷加IIS
}
至于Ctronl.Render时,是如何写入HtmlTextWriter,再写入HttpWriter,
再写回HttpWorkRequest,最终刷回内核,或使用socket发送回服务器,不在本文讨论范围.......
由上可见,Asp.net Ajax,必没有使用传统的HttpRequest.Filter来处理回发信息,而是使用了Asp.net 2.0内置的方式和回调的
Asp.net Ajax回调后呈现到客户端有二个部分,一部分是由RenderFormCallback生成的如下
RenderFormCallback部分会生成如下的客户端脚本
169|updatePanel|UpdatePanel1|\r\n
<input name=\"txt\" type=\"text\" value=\"wxy\" id=\"txt\" />\r\n
一部分是RenderPageCallback生成的
|__VIEWSTATE|/wEPDwUJNjg1NjA3NDcxZGRCX32AH2I/NEq+gCFrVr49kQDECw==|56
|hiddenField|__EVENTVALIDATION|/wEWAwKf344xAoznisYGApKGsMIJOfjKisKPYP0O2NXUpNjnA29hMlA=|0
|asyncPostBackControlIDs|||0|postBackControlIDs|||13|updatePanelIDs||tUpdatePanel1|0
|childUpdatePanelIDs|||12|panelsToRefreshIDs||UpdatePanel1|2|asyncPostBackTimeout||90|12
|formAction||Default.aspx|13|pageTitle||Untitled Page|
在客户端的部分Sys.WebForm._onFormSubmitCompleted()会对所有的信息以Json type:type,id:id,content:content进行封装
取出UpdatePanel,设置其innerhtml,客户端详细部分见赵老大的blogs