原创文章,如需转载,请注明出处。

 

使用ASP.NET AJAX框架我们可以搭建快速响应、具有丰富的用户体验的AJAX Web应用程序,而该框架的UpdatePanel控件则提供了一种非常简单的方式来实现Web页面的局部更新,我们不需要在每次回发的时候都加载整个页面。

 

那这个控件是如何实现这种局部刷新的哪,透过其实现机制我们可以更清楚其优缺点,便于我们确定其使用场合。本文将重点阐述ASP.NET AJAX控件UpdatePanel的实现机制。

 

1. ASP.NET AJAX 简介

ASP.NET AJAX是微软在ASP.NET 2.0之上对AJAX技术的一个封装,为Web应用程序提供完整的AJAX解决方案。ASP.NET AJAX有两种编程模型:部分更新和远程服务。

 

部分更新使得用户可以用传统的ASP.NET 2.0应用程序的方式来搭建AJAX应用,具体就是使用UpdatePanel控件来实现无闪烁页面更新。而远程服务则是直接通过前端JavaScript来调用的服务器端服务,前段获取数据后,进行页面更新,这就要求服务器端代码必须分解为特定于应用程序的服务,这是与传统的ASP.NET应用程序完全不同的体系结构。

 

部分更新着重于对现有应用程序进行渐进式增强,帮助用户逐渐转换到纯粹的AJAX应用。本文主要对部分更新编程模型中核心控件UpdatePanel的实现进行剖析,讲述其背后的故事。

 

ASP.NET AJAX框架分为客户端以及服务器端两个部分,基于客户端的 Microsoft AJAX Library包含了对浏览器兼容性、网络访问以及客户端控件组件等支持, 而服务器端则包括了服务器控件,Web 服务等等。

 

见下图:

 

ASP.NET AJAX UpdatePanel 控件实现剖析

 

Microsoft Ajax Library就是ASP.NET AJAX的客户端脚本库,其中MicrosoftAjax.js包含了ASP.NET AJAX的核心内容,包括跨浏览器的支持、基于面向对象对JavaScript的扩展以及网络访问等等。MicrosoftAjaxWebForm.js文件则是完全服务于ASP.NET AJAX页面局部更新这样一个功能的,在该文件中定义了一个客户端对象PageRequestManager,该对象将会负责客户端异步回送的全过程。

 

 

2. ScriptManager UpdatePanel

ScriptManager和UpdatePanel是ASP.NET AJAX服务器端中最重要的两个控件,ScriptManager控件用来管理ASP.NET页面中的客户端脚本,生成及注册所需要的客户端脚本,通过UpdatePanel控件可以更新页面的指定部分而无需加载整个页面。

 

 

 

看个例子:

ASP.NET AJAX UpdatePanel 控件实现剖析<form id="form1" runat="server">
ASP.NET AJAX UpdatePanel 控件实现剖析   
<asp:ScriptManager ID="ScriptManager1" runat="server">
ASP.NET AJAX UpdatePanel 控件实现剖析   
</asp:ScriptManager>
ASP.NET AJAX UpdatePanel 控件实现剖析   
<div>
ASP.NET AJAX UpdatePanel 控件实现剖析      
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
ASP.NET AJAX UpdatePanel 控件实现剖析           
<ContentTemplate>
ASP.NET AJAX UpdatePanel 控件实现剖析               
<%= DateTime.Now %>
ASP.NET AJAX UpdatePanel 控件实现剖析                
<br />
ASP.NET AJAX UpdatePanel 控件实现剖析               
<asp:Button ID="Button1" runat="server" Text="Button" />
ASP.NET AJAX UpdatePanel 控件实现剖析           
</ContentTemplate>
ASP.NET AJAX UpdatePanel 控件实现剖析       
</asp:UpdatePanel>
ASP.NET AJAX UpdatePanel 控件实现剖析   
</div>
ASP.NET AJAX UpdatePanel 控件实现剖析
</form>

 

 

构建如上代码所示的页面,在Runtime点击UpdatePanel中的Button控件,则不会引起整个页面刷新,只是用来显示当前时间的Label得到更新。

这是如何实现的哪?

 

3. ASP.NET AJAX部分呈现剖析

 

3.1 先从客户端讲起

 

看一下上面的示例代码在客户端的HTML代码, 这里只列出核心部分,其他全部隐去。

 

ASP.NET AJAX UpdatePanel 控件实现剖析

 

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析<script type="text/javascript">ASP.NET AJAX UpdatePanel 控件实现剖析
ASP.NET AJAX UpdatePanel 控件实现剖析
//<![CDATA[
ASP.NET AJAX UpdatePanel 控件实现剖析
Sys.WebForms.PageRequestManager._initialize('ScriptManager1', document.getElementById('form1'));
ASP.NET AJAX UpdatePanel 控件实现剖析Sys.WebForms.PageRequestManager.getInstance()._updateControls([
'tUpdatePanel1'], [], [], 90);
ASP.NET AJAX UpdatePanel 控件实现剖析
//]]>
ASP.NET AJAX UpdatePanel 控件实现剖析
</script>
ASP.NET AJAX UpdatePanel 控件实现剖析
ASP.NET AJAX UpdatePanel 控件实现剖析
<div id="UpdatePanel1">    
ASP.NET AJAX UpdatePanel 控件实现剖析     7/25/2008 4:54:36 PM
ASP.NET AJAX UpdatePanel 控件实现剖析     
<br />
ASP.NET AJAX UpdatePanel 控件实现剖析     
<input type="submit" name="Button1" value="Button" id="Button1" />            
ASP.NET AJAX UpdatePanel 控件实现剖析
</div>

     

看一下上面的两句JavaScript代码,第一句代码中的_initialize 方法是客户端PageRequestManager对象上的静态方法,它会创建一个 PageRequestManager 类的全局实例,并将其初始化。在这个初始化函数中,ageRequestManager对象注册了当前表单对象的submit事件,以及window对象的load和unload事件。

 

而第二句代码则是通过PageRequestManager的getInstance方法来检索其唯一实例, 得到该实例后调用_updateControls方法来注册UpdatePanel以及其Trigger控件。

 

我们可以从MicrosoftAjaxWebForm.js文件中得到_updateControls方法的声明:

function Sys$WebForms$PageRequestManager$_updateControls(updatePanelIDs, asyncPostBackControlIDs, postBackControlIDs, asyncPostBackTimeout) {}

其中第一个参数代表了当前页面上所有的UpdatePanel控件的ID集合,如果该UpdatePanel的ChildrenAsTrigger为True的话,应在ID前添加字符't',否则添加字符'f';而第二个参数是所有引发异步回送的控件ID;第三个参数是所有引发同步回送的控件ID;第四个参数设定了异步回送的Timeout时间,单位为秒。


由于PageRequestManager对象注册了当前表单的submit时间,所以每当页面有提交动作的时候,PageRequestManager对象就会介入,看一下PageRequestManager对象页面提交处理函数_onFormSubmit(evt)。

 

如果需要执行一次异步回送的话,会中止原有的普通浏览器会回发,代之使用XMLHttpRequest进行AJAX回发。在封装这个请求的时候,当前页面的所有字段以及视图状态都会被打包在请求中,另外还设置了这次Request的HTTP头:request.get_headers()['X-MicrosoftAjax'] = 'Delta=true';

 

在服务器端将会根据这个HTTP头标记来判定是否为一次AJAX异步回发。

 

_onFormSubmit(evt)函数代码:

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析Code
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析function Sys$WebForms$PageRequestManager$_onFormSubmit(evt) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析        
var continueSubmit = true;
ASP.NET AJAX UpdatePanel 控件实现剖析        
var isCrossPost = this._isCrossPost;
ASP.NET AJAX UpdatePanel 控件实现剖析        
this._isCrossPost = false;
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (this._onsubmit) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            continueSubmit 
= this._onsubmit();
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (continueSubmit) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
for (var i = 0; i < this._onSubmitStatements.length; i++ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析                
if (!this._onSubmitStatements[i]()) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                    continueSubmit 
= false;
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                }

ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (!continueSubmit) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
if (evt) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                evt.preventDefault();
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析            
return;
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        
var form = this._form;
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (isCrossPost) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
return;
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (this._activeDefaultButton && !this._activeDefaultButtonClicked) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._onFormElementActive(this._activeDefaultButton, 00);
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (!this._postBackSettings.async) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
return;
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        
var formBody = new Sys.StringBuilder();
ASP.NET AJAX UpdatePanel 控件实现剖析        formBody.append(encodeURIComponent(
this._scriptManagerID) + '=' + encodeURIComponent(this._postBackSettings.panelID) + '&');
ASP.NET AJAX UpdatePanel 控件实现剖析        
var count = form.elements.length;
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
for (var i = 0; i < count; i++ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
var element = form.elements[i];
ASP.NET AJAX UpdatePanel 控件实现剖析            
var name = element.name;
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
if (typeof(name) === "undefined" || (name === null|| (name.length === 0)) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                
continue;
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析            
var tagName = element.tagName;
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
if (tagName === 'INPUT'ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                
var type = element.type;
ASP.NET AJAX UpdatePanel 控件实现剖析                
if ((type === 'text'||
ASP.NET AJAX UpdatePanel 控件实现剖析                    (type 
=== 'password'||
ASP.NET AJAX UpdatePanel 控件实现剖析                    (type 
=== 'hidden'||
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析                    (((type 
=== 'checkbox'|| (type === 'radio')) && element.checked)) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                    formBody.append(encodeURIComponent(name));
ASP.NET AJAX UpdatePanel 控件实现剖析                    formBody.append(
'=');
ASP.NET AJAX UpdatePanel 控件实现剖析                    formBody.append(encodeURIComponent(element.value));
ASP.NET AJAX UpdatePanel 控件实现剖析                    formBody.append(
'&');
ASP.NET AJAX UpdatePanel 控件实现剖析                }

ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
else if (tagName === 'SELECT'ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                
var optionCount = element.options.length;
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析                
for (var j = 0; j < optionCount; j++ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                    
var option = element.options[j];
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析                    
if (option.selected) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                        formBody.append(encodeURIComponent(name));
ASP.NET AJAX UpdatePanel 控件实现剖析                        formBody.append(
'=');
ASP.NET AJAX UpdatePanel 控件实现剖析                        formBody.append(encodeURIComponent(option.value));
ASP.NET AJAX UpdatePanel 控件实现剖析                        formBody.append(
'&');
ASP.NET AJAX UpdatePanel 控件实现剖析                    }

ASP.NET AJAX UpdatePanel 控件实现剖析                }

ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
else if (tagName === 'TEXTAREA'ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                formBody.append(encodeURIComponent(name));
ASP.NET AJAX UpdatePanel 控件实现剖析                formBody.append(
'=');
ASP.NET AJAX UpdatePanel 控件实现剖析                formBody.append(encodeURIComponent(element.value));
ASP.NET AJAX UpdatePanel 控件实现剖析                formBody.append(
'&');
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (this._additionalInput) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            formBody.append(
this._additionalInput);
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._additionalInput = null;
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        
ASP.NET AJAX UpdatePanel 控件实现剖析        
var request = new Sys.Net.WebRequest();
ASP.NET AJAX UpdatePanel 控件实现剖析        
var action = form.action;
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (Sys.Browser.agent === Sys.Browser.InternetExplorer) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
var queryIndex = action.indexOf('?');
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
if (queryIndex !== -1ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                
var path = action.substr(0, queryIndex);
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析                
if (path.indexOf("%"=== -1ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                    action 
= encodeURI(path) + action.substr(queryIndex);
ASP.NET AJAX UpdatePanel 控件实现剖析                }

ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
else if (action.indexOf("%"=== -1ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                action 
= encodeURI(action);
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        request.set_url(action);
ASP.NET AJAX UpdatePanel 控件实现剖析        request.get_headers()[
'X-MicrosoftAjax'= 'Delta=true';
ASP.NET AJAX UpdatePanel 控件实现剖析        request.get_headers()[
'Cache-Control'= 'no-cache';
ASP.NET AJAX UpdatePanel 控件实现剖析        request.set_timeout(
this._asyncPostBackTimeout);
ASP.NET AJAX UpdatePanel 控件实现剖析        request.add_completed(Function.createDelegate(
thisthis._onFormSubmitCompleted));
ASP.NET AJAX UpdatePanel 控件实现剖析        request.set_body(formBody.toString());
ASP.NET AJAX UpdatePanel 控件实现剖析        
var handler = this._get_eventHandlerList().getHandler("initializeRequest");
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (handler) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
var eventArgs = new Sys.WebForms.InitializeRequestEventArgs(request, this._postBackSettings.sourceElement);
ASP.NET AJAX UpdatePanel 控件实现剖析            handler(
this, eventArgs);
ASP.NET AJAX UpdatePanel 控件实现剖析            continueSubmit 
= !eventArgs.get_cancel();
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (!continueSubmit) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
if (evt) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                evt.preventDefault();
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析            
return;
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        
this._scrollPosition = this._getScrollPosition();
ASP.NET AJAX UpdatePanel 控件实现剖析        
this.abortPostBack();
ASP.NET AJAX UpdatePanel 控件实现剖析        handler 
= this._get_eventHandlerList().getHandler("beginRequest");
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (handler) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
var eventArgs = new Sys.WebForms.BeginRequestEventArgs(request, this._postBackSettings.sourceElement);
ASP.NET AJAX UpdatePanel 控件实现剖析            handler(
this, eventArgs);
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (this._originalDoCallback) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._cancelPendingCallbacks();
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        
this._request = request;
ASP.NET AJAX UpdatePanel 控件实现剖析        request.invoke();
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (evt) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            evt.preventDefault();
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析    }

 

我们可以发现AJAX回发所提交的数据量其实跟普通回发过程中提交的数据量是一样的,并且还附加了一些额外信息。


 

3.2 服务器端的处理

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

 

AJAX回发引起的请求生命周期:

ASP.NET AJAX UpdatePanel 控件实现剖析

从上图我们可以看到,页面的生命周期与普通回发是一样的,同样页面上的控件也会经历相应的生命周期。

先了解一下ScriptManager控件在服务器端的处理:

 

- OnInit:在Init事件中,ScriptManager控件会注册页面的InitComplete, PreRenderComplete以及PreRender事件,另外还会根据本次请求的HTTP头来设定一个标记以确定本次回发是否为Ajax异步更新所引起的回发。

见下面的代码:

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析Code
ASP.NET AJAX UpdatePanel 控件实现剖析protected internal override void OnInit(EventArgs e)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析    
base.OnInit(e);
ASP.NET AJAX UpdatePanel 控件实现剖析    
if (this.EnableHistory)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析    
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析        
this.RegisterAsyncPostBackControl(this);
ASP.NET AJAX UpdatePanel 控件实现剖析    }

ASP.NET AJAX UpdatePanel 控件实现剖析    
if (!base.DesignMode)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析    
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析        IPage iPage 
= this.IPage;
ASP.NET AJAX UpdatePanel 控件实现剖析        
if (GetCurrent(this.Page) != null)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
throw new InvalidOperationException(AtlasWeb.ScriptManager_OnlyOneScriptManager);
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        iPage.Items[
typeof(IScriptManager)] = this;
ASP.NET AJAX UpdatePanel 控件实现剖析        iPage.Items[
typeof(ScriptManager)] = this;
ASP.NET AJAX UpdatePanel 控件实现剖析        iPage.InitComplete 
+= new EventHandler(this.OnPageInitComplete);
ASP.NET AJAX UpdatePanel 控件实现剖析        iPage.PreRenderComplete 
+= new EventHandler(this.OnPagePreRenderComplete);
ASP.NET AJAX UpdatePanel 控件实现剖析        
if (iPage.IsPostBack)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._isInAsyncPostBack = PageRequestManager.IsAsyncPostBackRequest(iPage.Request.Headers);
ASP.NET AJAX UpdatePanel 控件实现剖析            
if (this.EnableHistory)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                
this._isNavigating = iPage.Request["__EVENTTARGET"== this.UniqueID;
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        
this.PageRequestManager.OnInit();
ASP.NET AJAX UpdatePanel 控件实现剖析        iPage.PreRender 
+= new EventHandler(this.ScriptControlManager.OnPagePreRender);
ASP.NET AJAX UpdatePanel 控件实现剖析    }

ASP.NET AJAX UpdatePanel 控件实现剖析}

 

    

- OnPagePreRenderComplete,在PagePreRenderComplete事件中,ScriptManager控件会注册脚本文件以及Services代理脚本,MicrosoftAjax.js和MicrosoftAjaxWebForm.js就是在这个阶段被注册到客户端的。

见下面的代码:

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析Code
ASP.NET AJAX UpdatePanel 控件实现剖析private void OnPagePreRenderComplete(object sender, EventArgs e)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析    
if (!this.IsInAsyncPostBack)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析    
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析        
if (this.SupportsPartialRendering)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
this.IPage.ClientScript.GetPostBackEventReference(new PostBackOptions(thisnullnullfalsefalsefalsefalsetruenull));
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        
this.RegisterGlobalizationScriptBlock();
ASP.NET AJAX UpdatePanel 控件实现剖析        
this.RegisterScripts();
ASP.NET AJAX UpdatePanel 控件实现剖析        
this.RegisterServices();
ASP.NET AJAX UpdatePanel 控件实现剖析        
if (this.EnableHistory)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            JavaScriptSerializer serializer 
= JavaScriptSerializer.CreateInstance();
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
string[] strArray = new string[] ASP.NET AJAX UpdatePanel 控件实现剖析"\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" };
ASP.NET AJAX UpdatePanel 控件实现剖析            
string script = string.Concat(strArray);
ASP.NET AJAX UpdatePanel 控件实现剖析            RegisterStartupScript(
thistypeof(ScriptManager), "HistoryStartup", script, true);
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析    }

ASP.NET AJAX UpdatePanel 控件实现剖析    
else
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析    
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析        
this.RegisterScripts();
ASP.NET AJAX UpdatePanel 控件实现剖析        
if (this.EnableHistory)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
if ((this._initialState != null&& (this._initialState.Count == 0))
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                
this._initialState = null;
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析            
if (this._newPointCreated)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                
this.RegisterDataItem(this"'" + this.GetStateString() + "'"true);
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析    }

ASP.NET AJAX UpdatePanel 控件实现剖析}

 

- OnPreRender,在PreRender事件中如果判定本次回发为AJAX回发,则会调用PageRequestManager对象的OnPreRender方法。而PageRequestManager对象则会调用Page对象的SetRenderMethodDelegate方法来代理Page的画法,PageRequestManager对象会真正负责本次AJAX回发最终的HTML代码。

见下面的代码:

ASP.NET AJAX UpdatePanel 控件实现剖析public class ScriptManager : Control, ASP.NET AJAX UpdatePanel 控件实现剖析
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析   
protected internal override void OnPreRender(EventArgs e)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析   
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析       
base.OnPreRender(e);
ASP.NET AJAX UpdatePanel 控件实现剖析       
if (this.IsInAsyncPostBack)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析       
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析           
this.PageRequestManager.OnPreRender();
ASP.NET AJAX UpdatePanel 控件实现剖析       }

ASP.NET AJAX UpdatePanel 控件实现剖析   }

ASP.NET AJAX UpdatePanel 控件实现剖析}

ASP.NET AJAX UpdatePanel 控件实现剖析
ASP.NET AJAX UpdatePanel 控件实现剖析
internal sealed class PageRequestManager
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析   
internal void OnPreRender()
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析   
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析        
this._owner.IPage.SetRenderMethodDelegate(new RenderMethod(this.RenderPageCallback));
ASP.NET AJAX UpdatePanel 控件实现剖析   }

ASP.NET AJAX UpdatePanel 控件实现剖析}

 

 

PageRequestManager的RenderPageCallback方法最终处理了AJAX回发所需要的HTML代码,在这个方法中会遍历页面上所有涉及到的UpdatePanel控件,得到其更新后的HTML代码后,与隐藏字段还有一些额外信息一起打包,然后传递给客户端。

见下面的代码:

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析Code
ASP.NET AJAX UpdatePanel 控件实现剖析private void RenderPageCallback(HtmlTextWriter writer, Control pageControl)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析    
this.ProcessUpdatePanels();
ASP.NET AJAX UpdatePanel 控件实现剖析    IHttpResponse response 
= this._owner.IPage.Response;
ASP.NET AJAX UpdatePanel 控件实现剖析    response.ContentType 
= "text/plain";
ASP.NET AJAX UpdatePanel 控件实现剖析    response.Cache.SetNoServerCaching();
ASP.NET AJAX UpdatePanel 控件实现剖析    IHtmlForm form 
= this._owner.IPage.Form;
ASP.NET AJAX UpdatePanel 控件实现剖析    form.SetRenderMethodDelegate(
new RenderMethod(this.RenderFormCallback));
ASP.NET AJAX UpdatePanel 控件实现剖析    
this._updatePanelWriter = writer;
ASP.NET AJAX UpdatePanel 控件实现剖析    ParserStringWriter writer2 
= new ParserStringWriter();
ASP.NET AJAX UpdatePanel 控件实现剖析    ParserHtmlTextWriter writer3 
= new ParserHtmlTextWriter(writer2);
ASP.NET AJAX UpdatePanel 控件实现剖析    writer2.ParseWrites 
= true;
ASP.NET AJAX UpdatePanel 控件实现剖析    form.RenderControl(writer3);
ASP.NET AJAX UpdatePanel 控件实现剖析    writer2.ParseWrites 
= false;
ASP.NET AJAX UpdatePanel 控件实现剖析    
foreach (KeyValuePair<stringstring> pair in writer2.HiddenFields)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析    
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析        
if (ControlUtil.IsBuiltInHiddenField(pair.Key))
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            EncodeString(writer, 
"hiddenField", pair.Key, pair.Value);
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析    }

ASP.NET AJAX UpdatePanel 控件实现剖析    EncodeString(writer, 
"asyncPostBackControlIDs"string.Empty, this.GetAsyncPostBackControlIDs(false));
ASP.NET AJAX UpdatePanel 控件实现剖析    EncodeString(writer, 
"postBackControlIDs"string.Empty, this.GetPostBackControlIDs(false));
ASP.NET AJAX UpdatePanel 控件实现剖析    EncodeString(writer, 
"updatePanelIDs"string.Empty, this.GetAllUpdatePanelIDs());
ASP.NET AJAX UpdatePanel 控件实现剖析    EncodeString(writer, 
"childUpdatePanelIDs"string.Empty, this.GetChildUpdatePanelIDs());
ASP.NET AJAX UpdatePanel 控件实现剖析    EncodeString(writer, 
"panelsToRefreshIDs"string.Empty, this.GetRefreshingUpdatePanelIDs());
ASP.NET AJAX UpdatePanel 控件实现剖析    EncodeString(writer, 
"asyncPostBackTimeout"string.Empty, this._owner.AsyncPostBackTimeout.ToString(CultureInfo.InvariantCulture));
ASP.NET AJAX UpdatePanel 控件实现剖析    
if (writer3.FormAction != null)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析    
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析        EncodeString(writer, 
"formAction"string.Empty, writer3.FormAction);
ASP.NET AJAX UpdatePanel 控件实现剖析    }

ASP.NET AJAX UpdatePanel 控件实现剖析    
if (this._owner.IPage.Header != null)
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析    
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析        
string title = this._owner.IPage.Title;
ASP.NET AJAX UpdatePanel 控件实现剖析        
if (!string.IsNullOrEmpty(title))
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            EncodeString(writer, 
"pageTitle"string.Empty, title);
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析    }

ASP.NET AJAX UpdatePanel 控件实现剖析    
this.RenderDataItems(writer);
ASP.NET AJAX UpdatePanel 控件实现剖析    
this.ProcessScriptRegistration(writer);
ASP.NET AJAX UpdatePanel 控件实现剖析    
this.ProcessFocus(writer);
ASP.NET AJAX UpdatePanel 控件实现剖析}

 

 

 

3.3 客户端更新

当服务器端相应完毕后,客户端会得到响应信息,然后调用客户端对象PageRequestManager的_onFormSubmitCompleted方法来进行页面局部更新,最终会调用_updatePanel方法来更新UpdatePanel控件。

参见_onFormSubmitCompleted方法的代码:

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析Code
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析function Sys$WebForms$PageRequestManager$_onFormSubmitCompleted(sender, eventArgs) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析        
this._processingRequest = true;
ASP.NET AJAX UpdatePanel 控件实现剖析        var delimitByLengthDelimiter 
= '|';
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (sender.get_timedOut()) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._endPostBack(this._createPageRequestManagerTimeoutError(), sender);
ASP.NET AJAX UpdatePanel 控件实现剖析            
return;
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (sender.get_aborted()) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._endPostBack(null, sender);
ASP.NET AJAX UpdatePanel 控件实现剖析            
return;
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (!this._request || sender.get_webRequest() !== this._request) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
return;
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        var errorMessage;
ASP.NET AJAX UpdatePanel 控件实现剖析        var delta 
= [];
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (sender.get_statusCode() !== 200ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._endPostBack(this._createPageRequestManagerServerError(sender.get_statusCode()), sender);
ASP.NET AJAX UpdatePanel 控件实现剖析            
return;
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        var reply 
= sender.get_responseData();
ASP.NET AJAX UpdatePanel 控件实现剖析        var delimiterIndex, len, type, id, content;
ASP.NET AJAX UpdatePanel 控件实现剖析        var replyIndex 
= 0;
ASP.NET AJAX UpdatePanel 控件实现剖析        var parserErrorDetails 
= null;
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
while (replyIndex < reply.length) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            delimiterIndex 
= reply.indexOf(delimitByLengthDelimiter, replyIndex);
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
if (delimiterIndex === -1ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                parserErrorDetails 
= this._findText(reply, replyIndex);
ASP.NET AJAX UpdatePanel 控件实现剖析                
break;
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析            len 
= parseInt(reply.substring(replyIndex, delimiterIndex), 10);
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
if ((len % 1!== 0ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                parserErrorDetails 
= this._findText(reply, replyIndex);
ASP.NET AJAX UpdatePanel 控件实现剖析                
break;
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析            replyIndex 
= delimiterIndex + 1;
ASP.NET AJAX UpdatePanel 控件实现剖析            delimiterIndex 
= reply.indexOf(delimitByLengthDelimiter, replyIndex);
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
if (delimiterIndex === -1ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                parserErrorDetails 
= this._findText(reply, replyIndex);
ASP.NET AJAX UpdatePanel 控件实现剖析                
break;
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析            type 
= reply.substring(replyIndex, delimiterIndex);
ASP.NET AJAX UpdatePanel 控件实现剖析            replyIndex 
= delimiterIndex + 1;
ASP.NET AJAX UpdatePanel 控件实现剖析            delimiterIndex 
= reply.indexOf(delimitByLengthDelimiter, replyIndex);
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
if (delimiterIndex === -1ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                parserErrorDetails 
= this._findText(reply, replyIndex);
ASP.NET AJAX UpdatePanel 控件实现剖析                
break;
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析            id 
= reply.substring(replyIndex, delimiterIndex);
ASP.NET AJAX UpdatePanel 控件实现剖析            replyIndex 
= delimiterIndex + 1;
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
if ((replyIndex + len) >= reply.length) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                parserErrorDetails 
= this._findText(reply, reply.length);
ASP.NET AJAX UpdatePanel 控件实现剖析                
break;
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析            content 
= reply.substr(replyIndex, len);
ASP.NET AJAX UpdatePanel 控件实现剖析            replyIndex 
+= len;
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
if (reply.charAt(replyIndex) !== delimitByLengthDelimiter) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                parserErrorDetails 
= this._findText(reply, replyIndex);
ASP.NET AJAX UpdatePanel 控件实现剖析                
break;
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析            replyIndex
++;
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            Array.add(delta, 
ASP.NET AJAX UpdatePanel 控件实现剖析{type: type, id: id, content: content});
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (parserErrorDetails) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._endPostBack(this._createPageRequestManagerParserError(String.format(Sys.WebForms.Res.PRM_ParserErrorDetails, parserErrorDetails)), sender);
ASP.NET AJAX UpdatePanel 控件实现剖析            
return;
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        var updatePanelNodes 
= [];
ASP.NET AJAX UpdatePanel 控件实现剖析        var hiddenFieldNodes 
= [];
ASP.NET AJAX UpdatePanel 控件实现剖析        var arrayDeclarationNodes 
= [];
ASP.NET AJAX UpdatePanel 控件实现剖析        var scriptBlockNodes 
= [];
ASP.NET AJAX UpdatePanel 控件实现剖析        var scriptStartupNodes 
= [];
ASP.NET AJAX UpdatePanel 控件实现剖析        var expandoNodes 
= [];
ASP.NET AJAX UpdatePanel 控件实现剖析        var onSubmitNodes 
= [];
ASP.NET AJAX UpdatePanel 控件实现剖析        var dataItemNodes 
= [];
ASP.NET AJAX UpdatePanel 控件实现剖析        var dataItemJsonNodes 
= [];
ASP.NET AJAX UpdatePanel 控件实现剖析        var scriptDisposeNodes 
= [];
ASP.NET AJAX UpdatePanel 控件实现剖析        var asyncPostBackControlIDsNode, postBackControlIDsNode,
ASP.NET AJAX UpdatePanel 控件实现剖析            updatePanelIDsNode, asyncPostBackTimeoutNode,
ASP.NET AJAX UpdatePanel 控件实现剖析            childUpdatePanelIDsNode, panelsToRefreshNode, formActionNode;
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
for (var i = 0; i < delta.length; i++ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            var deltaNode 
= delta[i];
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
switch (deltaNode.type) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "updatePanel":
ASP.NET AJAX UpdatePanel 控件实现剖析                    Array.add(updatePanelNodes, deltaNode);
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "hiddenField":
ASP.NET AJAX UpdatePanel 控件实现剖析                    Array.add(hiddenFieldNodes, deltaNode);
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "arrayDeclaration":
ASP.NET AJAX UpdatePanel 控件实现剖析                    Array.add(arrayDeclarationNodes, deltaNode);
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "scriptBlock":
ASP.NET AJAX UpdatePanel 控件实现剖析                    Array.add(scriptBlockNodes, deltaNode);
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "scriptStartupBlock":
ASP.NET AJAX UpdatePanel 控件实现剖析                    Array.add(scriptStartupNodes, deltaNode);
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "expando":
ASP.NET AJAX UpdatePanel 控件实现剖析                    Array.add(expandoNodes, deltaNode);
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "onSubmit":
ASP.NET AJAX UpdatePanel 控件实现剖析                    Array.add(onSubmitNodes, deltaNode);
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "asyncPostBackControlIDs":
ASP.NET AJAX UpdatePanel 控件实现剖析                    asyncPostBackControlIDsNode 
= deltaNode;
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "postBackControlIDs":
ASP.NET AJAX UpdatePanel 控件实现剖析                    postBackControlIDsNode 
= deltaNode;
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "updatePanelIDs":
ASP.NET AJAX UpdatePanel 控件实现剖析                    updatePanelIDsNode 
= deltaNode;
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "asyncPostBackTimeout":
ASP.NET AJAX UpdatePanel 控件实现剖析                    asyncPostBackTimeoutNode 
= deltaNode;
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "childUpdatePanelIDs":
ASP.NET AJAX UpdatePanel 控件实现剖析                    childUpdatePanelIDsNode 
= deltaNode;
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "panelsToRefreshIDs":
ASP.NET AJAX UpdatePanel 控件实现剖析                    panelsToRefreshNode 
= deltaNode;
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "formAction":
ASP.NET AJAX UpdatePanel 控件实现剖析                    formActionNode 
= deltaNode;
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "dataItem":
ASP.NET AJAX UpdatePanel 控件实现剖析                    Array.add(dataItemNodes, deltaNode);
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "dataItemJson":
ASP.NET AJAX UpdatePanel 控件实现剖析                    Array.add(dataItemJsonNodes, deltaNode);
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "scriptDispose":
ASP.NET AJAX UpdatePanel 控件实现剖析                    Array.add(scriptDisposeNodes, deltaNode);
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "pageRedirect":
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析                    
if (Sys.Browser.agent === Sys.Browser.InternetExplorer) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                        var anchor 
= document.createElement("a");
ASP.NET AJAX UpdatePanel 控件实现剖析                        anchor.style.display 
= 'none';
ASP.NET AJAX UpdatePanel 控件实现剖析                        anchor.attachEvent(
"onclick", cancelBubble);
ASP.NET AJAX UpdatePanel 控件实现剖析                        anchor.href 
= deltaNode.content;
ASP.NET AJAX UpdatePanel 控件实现剖析                        document.body.appendChild(anchor);
ASP.NET AJAX UpdatePanel 控件实现剖析                        anchor.click();
ASP.NET AJAX UpdatePanel 控件实现剖析                        anchor.detachEvent(
"onclick", cancelBubble);
ASP.NET AJAX UpdatePanel 控件实现剖析                        document.body.removeChild(anchor);
ASP.NET AJAX UpdatePanel 控件实现剖析                        
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析                        function cancelBubble(e) 
ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                            e.cancelBubble 
= true;
ASP.NET AJAX UpdatePanel 控件实现剖析                        }

ASP.NET AJAX UpdatePanel 控件实现剖析                    }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析                    
else ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                        window.location.href 
= deltaNode.content;
ASP.NET AJAX UpdatePanel 控件实现剖析                    }

ASP.NET AJAX UpdatePanel 控件实现剖析                    
return;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "error":
ASP.NET AJAX UpdatePanel 控件实现剖析                    
this._endPostBack(this._createPageRequestManagerServerError(Number.parseInvariant(deltaNode.id), deltaNode.content), sender);
ASP.NET AJAX UpdatePanel 控件实现剖析                    
return;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "pageTitle":
ASP.NET AJAX UpdatePanel 控件实现剖析                    document.title 
= deltaNode.content;
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
case "focus":
ASP.NET AJAX UpdatePanel 控件实现剖析                    
this._controlIDToFocus = deltaNode.content;
ASP.NET AJAX UpdatePanel 控件实现剖析                    
break;
ASP.NET AJAX UpdatePanel 控件实现剖析                
default:
ASP.NET AJAX UpdatePanel 控件实现剖析                    
this._endPostBack(this._createPageRequestManagerParserError(String.format(Sys.WebForms.Res.PRM_UnknownToken, deltaNode.type)), sender);
ASP.NET AJAX UpdatePanel 控件实现剖析                    
return;
ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        var i;
ASP.NET AJAX UpdatePanel 控件实现剖析        
if (asyncPostBackControlIDsNode && postBackControlIDsNode &&
ASP.NET AJAX UpdatePanel 控件实现剖析            updatePanelIDsNode 
&& panelsToRefreshNode &&
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            asyncPostBackTimeoutNode 
&& childUpdatePanelIDsNode) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._oldUpdatePanelIDs = this._updatePanelIDs;
ASP.NET AJAX UpdatePanel 控件实现剖析            var childUpdatePanelIDsString 
= childUpdatePanelIDsNode.content;
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._childUpdatePanelIDs = childUpdatePanelIDsString.length ? childUpdatePanelIDsString.split(',') : [];
ASP.NET AJAX UpdatePanel 控件实现剖析            var asyncPostBackControlIDsArray 
= this._splitNodeIntoArray(asyncPostBackControlIDsNode);
ASP.NET AJAX UpdatePanel 控件实现剖析            var postBackControlIDsArray 
= this._splitNodeIntoArray(postBackControlIDsNode);
ASP.NET AJAX UpdatePanel 控件实现剖析            var updatePanelIDsArray 
= this._splitNodeIntoArray(updatePanelIDsNode);
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._panelsToRefreshIDs = this._splitNodeIntoArray(panelsToRefreshNode);
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析            
for (i = 0; i < this._panelsToRefreshIDs.length; i++ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                var panelClientID 
= this._uniqueIDToClientID(this._panelsToRefreshIDs[i]);
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析                
if (!document.getElementById(panelClientID)) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析                    
this._endPostBack(Error.invalidOperation(String.format(Sys.WebForms.Res.PRM_MissingPanel, panelClientID)), sender);
ASP.NET AJAX UpdatePanel 控件实现剖析                    
return;
ASP.NET AJAX UpdatePanel 控件实现剖析                }

ASP.NET AJAX UpdatePanel 控件实现剖析            }

ASP.NET AJAX UpdatePanel 控件实现剖析            var asyncPostBackTimeout 
= asyncPostBackTimeoutNode.content;
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._updateControls(updatePanelIDsArray, asyncPostBackControlIDsArray, postBackControlIDsArray, asyncPostBackTimeout);
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
this._dataItems = ASP.NET AJAX UpdatePanel 控件实现剖析{};
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
for (i = 0; i < dataItemNodes.length; i++ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            var dataItemNode 
= dataItemNodes[i];
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._dataItems[dataItemNode.id] = dataItemNode.content;
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
for (i = 0; i < dataItemJsonNodes.length; i++ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            var dataItemJsonNode 
= dataItemJsonNodes[i];
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._dataItems[dataItemJsonNode.id] = Sys.Serialization.JavaScriptSerializer.deserialize(dataItemJsonNode.content);
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        var handler 
= this._get_eventHandlerList().getHandler("pageLoading");
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (handler) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            handler(
thisthis._getPageLoadingEventArgs());
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
if (formActionNode) ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            
this._form.action = formActionNode.content;
ASP.NET AJAX UpdatePanel 控件实现剖析        }

ASP.NET AJAX UpdatePanel 控件实现剖析        
ASP.NET AJAX UpdatePanel 控件实现剖析        
ASP.NET AJAX UpdatePanel 控件实现剖析        Sys._ScriptLoader.readLoadedScripts();
ASP.NET AJAX UpdatePanel 控件实现剖析        Sys.Application.beginCreateComponents();
ASP.NET AJAX UpdatePanel 控件实现剖析        var scriptLoader 
= Sys._ScriptLoader.getInstance();
ASP.NET AJAX UpdatePanel 控件实现剖析        
this._queueScripts(scriptLoader, scriptBlockNodes, truefalse);
ASP.NET AJAX UpdatePanel 控件实现剖析        
ASP.NET AJAX UpdatePanel 控件实现剖析ASP.NET AJAX UpdatePanel 控件实现剖析        
this._updateContext = ASP.NET AJAX UpdatePanel 控件实现剖析{
ASP.NET AJAX UpdatePanel 控件实现剖析            response: sender,
ASP.NET AJAX UpdatePanel 控件实现剖析            updatePanelNodes: updatePanelNodes,
ASP.NET AJAX UpdatePanel 控件实现剖析            scriptBlockNodes: scriptBlockNodes,
ASP.NET AJAX UpdatePanel 控件实现剖析            scriptDisposeNodes: scriptDisposeNodes,
ASP.NET AJAX UpdatePanel 控件实现剖析            hiddenFieldNodes: hiddenFieldNodes,
ASP.NET AJAX UpdatePanel 控件实现剖析            arrayDeclarationNodes: arrayDeclarationNodes,
ASP.NET AJAX UpdatePanel 控件实现剖析            expandoNodes: expandoNodes,
ASP.NET AJAX UpdatePanel 控件实现剖析            scriptStartupNodes: scriptStartupNodes,
ASP.NET AJAX UpdatePanel 控件实现剖析            onSubmitNodes: onSubmitNodes
ASP.NET AJAX UpdatePanel 控件实现剖析        }
;
ASP.NET AJAX UpdatePanel 控件实现剖析        scriptLoader.loadScripts(
0,
ASP.NET AJAX UpdatePanel 控件实现剖析            Function.createDelegate(
thisthis._scriptIncludesLoadComplete),
ASP.NET AJAX UpdatePanel 控件实现剖析            Function.createDelegate(
thisthis._scriptIncludesLoadFailed),
ASP.NET AJAX UpdatePanel 控件实现剖析            
null);
ASP.NET AJAX UpdatePanel 控件实现剖析}

 

4.结语

使用UpdatePanel是给已经存在的ASP.NET应用程序添加AJAX体验的最快捷方式,对于应用程序的架构也不会有影响,我们可以使用它来逐步的提高应用程序的用户体验。但是其性能与纯粹的AJAX方式相比较,还是比较差的。

 

转载于:https://www.cnblogs.com/tedzhao/archive/2008/07/29/1249871.html

相关文章:

  • 2021-07-24
  • 2021-05-23
  • 2021-05-26
  • 2021-12-14
  • 2021-12-10
  • 2021-09-29
  • 2022-02-12
  • 2021-10-27
猜你喜欢
  • 2021-10-01
  • 2022-12-23
  • 2021-11-12
相关资源
相似解决方案