3.2 服务器端的处理
AJAX回发请求到达服务器之后,当前页面的生命周期跟普通回发引起的请求是一样的,页面的Init、Load和Render等等事件都会被触发,差别只是在于AJAX回发使用了不同的呈现画法。
AJAX回发引起的请求生命周期:

从上图我们可以看到,页面的生命周期与普通回发是一样的,同样页面上的控件也会经历相应的生命周期。
先了解一下ScriptManager控件在服务器端的处理:
- OnInit:在Init事件中,ScriptManager控件会注册页面的InitComplete, PreRenderComplete以及PreRender事件,另外还会根据本次请求的HTTP头来设定一个标记以确定本次回发是否为Ajax异步更新所引起的回发。
见下面的代码:
protected internal override void OnInit(EventArgs e)
{
base.OnInit(e);
if (this.EnableHistory)
{
this.RegisterAsyncPostBackControl(this);
}
if (!base.DesignMode)
{
IPage iPage = this.IPage;
if (GetCurrent(this.Page) != null)
{
throw new InvalidOperationException(AtlasWeb.ScriptManager_OnlyOneScriptManager);
}
iPage.Items[typeof(IScriptManager)] = this;
iPage.Items[typeof(ScriptManager)] = this;
iPage.InitComplete += new EventHandler(this.OnPageInitComplete);
iPage.PreRenderComplete += new EventHandler(this.OnPagePreRenderComplete);
if (iPage.IsPostBack)
{
this._isInAsyncPostBack = PageRequestManager.IsAsyncPostBackRequest(iPage.Request.Headers);
if (this.EnableHistory)
{
this._isNavigating = iPage.Request["__EVENTTARGET"] == this.UniqueID;
}
}
this.PageRequestManager.OnInit();
iPage.PreRender += new EventHandler(this.ScriptControlManager.OnPagePreRender);
}
}- OnPagePreRenderComplete,在PagePreRenderComplete事件中,ScriptManager控件会注册脚本文件以及Services代理脚本,MicrosoftAjax.js和MicrosoftAjaxWebForm.js就是在这个阶段被注册到客户端的。
见下面的代码:
private void OnPagePreRenderComplete(object sender, EventArgs e)
{
if (!this.IsInAsyncPostBack)
{
if (this.SupportsPartialRendering)
{
this.IPage.ClientScript.GetPostBackEventReference(new PostBackOptions(this, null, null, false, false, false, false, true, null));
}
this.RegisterGlobalizationScriptBlock();
this.RegisterScripts();
this.RegisterServices();
if (this.EnableHistory)
{
JavaScriptSerializer serializer = JavaScriptSerializer.CreateInstance();
string[] strArray = new string[] { "\r\nSys.Application.setServerId(", serializer.Serialize(this.ClientID), ", ", serializer.Serialize(this.UniqueID), ");\r\n", ((this._initialState != null) && (this._initialState.Count != 0)) ? (" Sys.Application.setServerState('" + this.GetStateString() + "');\r\n") : "\r\n" };
string script = string.Concat(strArray);
RegisterStartupScript(this, typeof(ScriptManager), "HistoryStartup", script, true);
}
}
else
{
this.RegisterScripts();
if (this.EnableHistory)
{
if ((this._initialState != null) && (this._initialState.Count == 0))
{
this._initialState = null;
}
if (this._newPointCreated)
{
this.RegisterDataItem(this, "'" + this.GetStateString() + "'", true);
}
}
}
}
- OnPreRender,在PreRender事件中如果判定本次回发为AJAX回发,则会调用PageRequestManager对象的OnPreRender方法。而PageRequestManager对象则会调用Page对象的SetRenderMethodDelegate方法来代理Page的画法,PageRequestManager对象会真正负责本次AJAX回发最终的HTML代码。
见下面的代码:
public class ScriptManager : Control,
{
protected internal override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (this.IsInAsyncPostBack)
{
this.PageRequestManager.OnPreRender();
}
}
}
internal sealed class PageRequestManager
{
internal void OnPreRender()
{
this._owner.IPage.SetRenderMethodDelegate(new RenderMethod(this.RenderPageCallback));
}
}


