在ScriptManager类的OnPreRender方法中会判断此次PostBack是否为Ajax的Postback:
protected internal override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (this.IsInAsyncPostBack)
{
this.PageRequestManager.OnPreRender();
}
}
如果是是会调用PageRequestManager的OnPreRender方法:
internal void OnPreRender()
{
this._owner.IPage.SetRenderMethodDelegate(new RenderMethod(this.RenderPageCallback));
}
此方法中IPage即为request所要求的页面,接下来我们介绍SetRenderMethodDelegate方法:
public void SetRenderMethodDelegate(RenderMethod renderMethod)
{
this.RareFieldsEnsured.RenderMethod = renderMethod;
this.Controls.SetCollectionReadOnly("Collection_readonly_Codeblocks");
}
在此方法中我们将传入的方法赋值给了RareFieldsEnsured.RenderMethod。
下面我们介绍System.WebUI.Control类的RenderChildren方法:
protected internal virtual void RenderChildren(HtmlTextWriter writer)
{
ICollection children = this._controls;
this.RenderChildrenInternal(writer, children);
}
大家可以注意到它调用了私有方法RenderChildrenInternal:
internal void RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
{
if ((this.RareFields != null) && (this.RareFields.RenderMethod != null))
{
writer.BeginRender();
this.RareFields.RenderMethod(writer, this);
writer.EndRender();
}
else if (children != null)
{
foreach (Control control in children)
{
control.RenderControl(writer);
}
}
}
那么如果此次Postback是AjaxBack,通过上面的代码我们可以知道“if ((this.RareFields != null) && (this.RareFields.RenderMethod != null))”条件为真,那么他会调用我们前面在传入的PageRequestManager.RenderPageCallback方法:
private void RenderPageCallback(HtmlTextWriter writer, Control pageControl)
{
this.ProcessUpdatePanels();
System.Web.HttpResponseBase response = this._owner.IPage.Response;
response.ContentType = "text/plain";
response.Cache.SetNoServerCaching();
IHtmlForm form = this._owner.IPage.Form;
form.SetRenderMethodDelegate(new RenderMethod(this.RenderFormCallback));
this._updatePanelWriter = writer;
ParserStringWriter writer2 = new ParserStringWriter();
ParserHtmlTextWriter writer3 = new ParserHtmlTextWriter(writer2);
writer2.ParseWrites = true;
form.RenderControl(writer3);
writer2.ParseWrites = false;
foreach (KeyValuePair<string, string> pair in writer2.HiddenFields)
{
if (ControlUtil.IsBuiltInHiddenField(pair.Key))
{
EncodeString(writer, "hiddenField", pair.Key, pair.Value);
}
}
EncodeString(writer, "asyncPostBackControlIDs", string.Empty, this.GetAsyncPostBackControlIDs(false));
EncodeString(writer, "postBackControlIDs", string.Empty, this.GetPostBackControlIDs(false));
EncodeString(writer, "updatePanelIDs", string.Empty, this.GetAllUpdatePanelIDs());
EncodeString(writer, "childUpdatePanelIDs", string.Empty, this.GetChildUpdatePanelIDs());
EncodeString(writer, "panelsToRefreshIDs", string.Empty, this.GetRefreshingUpdatePanelIDs());
EncodeString(writer, "asyncPostBackTimeout", string.Empty, this._owner.AsyncPostBackTimeout.ToString(CultureInfo.InvariantCulture));
if (writer3.FormAction != null)
{
EncodeString(writer, "formAction", string.Empty, writer3.FormAction);
}
if (this._owner.IPage.Header != null)
{
string title = this._owner.IPage.Title;
if (!string.IsNullOrEmpty(title))
{
EncodeString(writer, "pageTitle", string.Empty, title);
}
}
this.RenderDataItems(writer);
this.ProcessScriptRegistration(writer);
this.ProcessFocus(writer);
}
在此方法中大家可以注意到我们他首先进行了Page的outPut的相关内容,然后通过form.SetRenderMethodDelegate(new RenderMethod(this.RenderFormCallback));将RenderFormCallback方法作为form的RenderChildren方法,接着通过form.RenderControl(writer3);调用RenderFormCallback方法输出form的output:
private void RenderFormCallback(HtmlTextWriter writer, Control containerControl)
{
ParserStringWriter innerWriter = writer.InnerWriter as ParserStringWriter;
innerWriter.ParseWrites = false;
if (this._updatePanelsToRefresh != null)
{
foreach (UpdatePanel panel in this._updatePanelsToRefresh)
{
if (panel.Visible)
{
panel.RenderControl(this._updatePanelWriter);
}
}
}
IPage iPage = this._owner.IPage;
if (iPage.EnableEventValidation)
{
TextWriter writer3 = null;
bool flag = false;
try
{
writer3 = iPage.Response.SwitchWriter(TextWriter.Null);
flag = true;
HtmlTextWriter writer4 = new HtmlTextWriter(TextWriter.Null);
foreach (Control control in containerControl.Controls)
{
control.RenderControl(writer4);
}
}
finally
{
if (flag)
{
iPage.Response.SwitchWriter(writer3);
}
}
}
innerWriter.ParseWrites = true;
}
在此方法中我们可以注意到他只是输出了UpdatePanel相关的内容。