- UpdatePanel如何实现部分呈现?
我们知道,使用UpdatePanel向服务器发送一个异步请求,服务器处理该请求,初始化控件树的过程跟处理一般的请求是没有任何区别的。但是为什么最终向客户端呈现的只是UpdatePanel包含的控件内容,而不是整个控件树的内容呢?难道是ScriptManager偷偷的把其他的控件移除了吗?
答案是否定的。
ScriptManager控件首先是个普通的控件,在初始化时注册了一个RenderPageCallback函数,该函数在预呈现的时候执行。该函数中有一个关键的语句:
form.SetRenderMethodDelegate(new RenderMethod(this.RenderFormCallback));
该方法为form控件注册了一个RenderMethod方法RenderFormCallback,该方法就是呈现UpdatePanel里的内容的逻辑。为什么注册了RenderMethod方法就可以让其他的控件不被呈现,关键在于Control的RenderChildrenInternal方法。假如RenderMethod代理不为空,它就不会呈现自己的子控件!!!
internal HtmlTextWriter writer, RareFields != null) && (this.RenderMethod != null)) //不会呈现自己的子控件 { writer.RareFields.EndRender(); } else if (children != null) { foreach (RenderControl(writer); } } } |
- UpdatePanel如何知道页面里没有ScriptManger控件?
当我们使用UpdatePanel时,如果没有拖一个ScriptManager控件到页面里。将会抛一个异常。UpdatePanel是如何知道的?
这是因为Page类里有一个Items属性,UpdatePanel在初始化的时候通过使用Page.Items[typeof(ScriptManager)] 获取ScriptManager的实例,如果为空则抛异常。我们可以推断出,ScriptManager在初始化的时候,会有这么一个语句Page.Items[typeof(ScriptManager)] = this。因此,ScriptManager必须放在UpdatePanel前面。同理,如果一个页面里放了两个ScriptManager也会抛出异常,原理也是一样的。
- UpdatePanel异步提交表单跟普通的提交有什么区别?
多两个Key-Value,
_ASYNCPOST true
<ScriptMangerId> <UpdatePanelId>|<TriggerControlId>
ASP.Net AJAX其实就是使用UpdatePanel控件和Ajax Control Toolkit服务器端控件,其他的客户端控件以及注册Javascript名字空间、类、接口和枚举都和AJAX没有直接的关系。
我对UpdatePanel的工作原理很感兴趣,在网上找到这篇文章,但还是没有完全解决我的疑惑。
UpdatePanel 可以用来创建丰富的局部更新Web应用程序,它是 ASP.NET 2.0 AJAX Extensions中(ASP.Net3.5中已经包含)很重要的一个控件,它的强大之处在于不用编写任何客户端脚本,只要在一个页面上添加几个 UpdatePanel 控件和一个 ScriptManager 控件就可以自动实现局部更新。
UpdatePanel 的工作依赖于 ScriptManager 服务端控件和客户端 PageRequestManager,当 ScriptManager 中允许页面局部更新时,它会以异步的方式回传给服务器,与传统的整页回传方式不同的是只有包含在 UpdatePanel 中的页面部分会被更新,在从服务端返回 HTML 之后,PageRequestManager 会通过操作 DOM 对象来替换需要更新的代码片段。
显然这里对服务器端和客户端的处理细节没有描述。这种粗糙的表述我自己都能够想象得到。接着寻找,找到了比较满意的答案。
UpdatePanel 依赖于服务端控件ScriptManager和客户端脚 本对象PageRequestManager。
Submit 被页面上的PageRequestManager截获, PageRequestManager会判断是传统提交还是异步提交。如果是异步提交,就使用XmlHttpRequest来提交,提交的内容除了传统提交的form外,还包含一个自定义的http header “x-myajax”来通知server端这是一个异步提交,然后和传统提交一样走完完整的生命周期。
Init
Load State
Process Postback
Load
Postback Events
Save State
PreRender
Render
UnLoad
在Render阶段,ScriptManager如果看到http header “x-myajax”标记,就会替换掉Page对象的输出方式,输出需要刷新的UpdatePanel中的内容和一些ViewState. 在收到服务端的处理结果之后,PageRequestManager会通过操作DOM对象来替换需要更新的代码片段。需要执行的JavaScript也会在此时传送到客户端执行.
异步请求的内容包含如下数据,与整页更新相比没有任何减少
– 采集Form中所有<input />并发送
– 包含ViewState
应该尽可能减少客户端接受到的数据大小,可以使用如下方式:
– 使用多个UpdatePanel包含多个部分
– UpdateMode尽量不要设为Always