惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
博客园 - Franky
GbyAI
GbyAI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
爱范儿
爱范儿
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
博客园_首页
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recent Announcements
Recent Announcements
Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
C
CERT Recently Published Vulnerability Notes
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
L
LangChain Blog
L
LINUX DO - 最新话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Hacker News: Front Page
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
AI
AI
T
Troy Hunt's Blog
Microsoft Azure Blog
Microsoft Azure Blog
阮一峰的网络日志
阮一峰的网络日志
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
罗磊的独立博客
S
Secure Thoughts
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
人人都是产品经理
人人都是产品经理
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
E
Exploit-DB.com RSS Feed
Attack and Defense Labs
Attack and Defense Labs

博客园 - dragonpro

初创公司招聘 程序员 平面设计师 软件销售(成都) 分享一组红白机音乐Remix 初识北京 2008,再会,深圳 顾客想要的和说的不一样 从String到enum的互换(string to enum to string) CommunityServer系列之十一:优秀的URL重写机制 Community Server系列之十:让CS2支持中文搜索 Community Server系列之九:CS2中的用户管理1(MemberRole) Community Server系列之八:CS2中的CSContext Community Server系列之七:快速找到需要修改的文件[技巧] Community Server系列之六:CS2中的关键词及数据结构 Community Server系列之四:Ajax在CS2.0中的应用1 Community Server系列之三:页面间关系2[介绍] Community Server系列之二:页面之间的关系1[介绍] Community Server系列之一:开篇简介 梦里的灵感 使用Enterprise Library DAAB架构灵活的数据提供层 异构数据库转换工具的结构说明
Community Server系列之五:CS2中的Ajax原理
dragonpro · 2006-04-26 · via 博客园 - dragonpro

上一节用了一个示例说明了AjaxCS2中的一点简单的应用,这一节里着重探讨一下CS2中的Ajax的高级应用和实现原理,在了解Ajax的实现原理前我觉得有必要先了解一下aspx页面从请求到返回HTML都做了些什么,我想在了解了页面处理机制再来认识Ajax处理原理应该应该会很有帮助的,见下表:

序号

阶段

页面事件

可覆盖的方法

1

页面初始化

Init

2

加载视图状态

LoadViewState

3

处理回发数据

任意实现 IPostBackDataHandler 接口的控件中的 LoadPostData 方法

4

加载页面

Load

5

回发更改通知

任意实现 IPostBackDataHandler 接口的控件中的 RaisePostDataChangedEvent 方法

6

处理回发事件

由控件定义的任意回发事件

任意实现 IPostBackDataHandler 接口的控件中的 RaisePostBackEvent 方法

7

页面显示前阶段

PreRender

8

保存视图状态

SaveViewState

9

显示页面

Render

10

卸载页面

Unload

此表从上到下为处理ASPX页面所经历的过程,现简单解说一下各过程处理的工作:

1.              在页面实例化所有控件之后触发,页面的控件也仅仅是实例化好了,各静态变量也有了初始值,在这个事件里,一般我们可以设置一些事件处理程序等等。

2.              如果是回发那么加载视图状态。

3.              处理回发数据,为控件赋值,这里通过读取回发过来的数据初始化各控件的属性。这样,第一步生成的控件就会有值了。

4.              激发Load事件

5.              处理比如OnChange这样的事件,也就是控件属性和ViewState中的值不同的话,将会激发事件处理程序。

6.              处理页面里的按钮等回发事件。

7.              页面即将展现给用户,也就是即将生成HTML代码前激发的事件,注意这个地方是我们的Ajax关键事件,在这里页面前的初始化和相关事件都处理完了,服务器控件已经具有该有的值了,而Ajax应用只会返回给客户段一小部分HTML或字符串,作为客户端调用AjaxPostBack的返回值,显然此处不下手还等待何时呢,在这里,筛选出我们想要返回给客户端的对象并且只呈现这些对象即可,而执行完这些对象的Render方法之后即可停止Response数据了。

8.              保存视图状态,在aspx中视图状态保存在客户端HTML的隐藏字段__VIEWSTATE中。

9.              依次执行各个控件的Render方法,输出需要呈现的HTML标签,Render方法是asp.net中很关键的方法,每个服务器控件都有相应的Render方法,它的目的就是把自己生成HTML格式的字符串,此字符串最终返回给客户端的浏览器。

10.           最后一步触发卸载页面事件,我们可以在此处理资源回收等操作。

了解了此原理后,我想要理解Ajax的运行原理应该不是大问题了,让我们再了解一下Ajax都有哪些操作,我想不外乎两种方式,一种是不返回值或返回简单字符串形式,客户端通过这点标识操作一些功能,另外一种方式是返回HTML格式内容,比如在网页里的某个区块的动态加载内容,这两种方式大同小意,我们的Ajax在后台都是相似的处理,我想要说明处理过程还是结合示例来说比较通俗,现在就拿在CS2中经常用到的AjaxPager这个控件来说,这个控件在CS2中算是比较高级一点的应用了,与我们的第三方Ajax控件比较类似,使用方法既是在AjaxPager控件里嵌入相应的服务器控件(比如Repeater控件)以后就可以使里面的内容无刷新分页显示数据了,表面上看来是很高深很酷的功能,其实处理过程并不是想象中的那般复杂。

<CS:AjaxPager runat="Server" id="PostsPager" ShowFirstLastLinks="false">

                                                        
<asp:Repeater id="Posts" runat="Server" >

                                                               
<ItemTemplate>

                                                                      
<div class="CommonSidebarContentItem">

                                                                             
<asp:HyperLink Runat="server" id="TitleLink" />

                                                                      
</div>

                                                               
</ItemTemplate>

                                                        
</asp:Repeater>

                                                 
</CS:AjaxPager>

大致分析一下此控件的工作流程:此控件为分页控件,在页面加载的时候赋上分页属性,计算页数,并生成相应的Ajax分页连接,当用户点击分页连接的时候,页面在后台进行ajax提交,通过服务器处理后返回HTML形式的提交结果,并通过js脚本呈现到浏览器上。

AjaxPager

关键一点是让程序注册PreRender处理事件,我们知道,在此事件控件还没有生成HTML代码,也就是Response对象里还没有具体的HTML代码,所有的控件还没有执行Reader方法,这里我们就可以选择想执行Reader方法的控件而忽略其他控件,在此我们只需要执行包含在AjaxPager控件内的控件(也就是AjaxPager的子控件)的Reader方法, 这样就可以保证Response给客户端的是纯净的,只在AjaxPager控件内部的控件的HTML实现。

让我看看此控件重写的OnInit方法,此方法里的AjaxManager.Register(this, "AjaxPager");这一句在前面一章已经介绍过,为注册Ajax的回发脚本,当然它还有另外一个作用那就是注册PreRender事件,当触发PreReader事件 到时候,AjaxManager会去找控件里具有AjaxMethod属性的方法来执行,让我们看看在AjaxPager里的AjaxMethod都干了些什么:

[AjaxMethod(IncludeControlValuesWithCallBack=true)]

         
public virtual string GetPage(int page)

         
{

              StringWriter stringWriter 
= new StringWriter();

              HtmlTextWriter htmlWriter 
= new HtmlTextWriter(stringWriter);

 

              AddPageLinks();

              AddPreviousNextLinks();

 

              
if (this.ShowFirstLastLinks)

                   AddFirstLastLinks();

 

              
this.Render(htmlWriter, false);

 

              
return stringWriter.ToString();

          }


可以看出,倒数第二句就是Reader方法,输出的HTML保存到HtmlTextWriter中,最后一句即是把控件的HTML呈现字符串对象返回给调用者(这里指的是AjaxManager),AjaxManager获得值后按照指定的格式Response到客户端,并中止其他的Response,客户端通过调用document.getElementById(‘’).innerHTML = result.value来向浏览器呈现指定区域的数据。