ASP.NET之母版,页面生命周期,缓存,缓存依赖
母版页 MastePager iframe框架是在当前页面里再嵌套一个页面.
1.子页面中的Page_Load()先执行 母版页的Page_Load()再执行 子页面继承Page类,而母版页没有继承Page类, 调用页面的 PR方法时会先执行子页面的PageLoad方法
2.设置页面的命令行 Trace=true,开启生命周期跟踪模式 1.PerformPreInit();为当前页面对象进行预初始化处理,加载样式表(皮肤等) 2.InitRecursive(null);递归初始化操作,属于Control类的,递归当前控件树中每个控件 3.OnInitComplete(EventArgs.Empty); 完成所有初始化工作. //自动事件注册机制, 关闭AutoEventWireup="false" 4.LoadAllState();经过反base64编码以及反序列化,将页面viewstate属性中的值还原到控件属性和自定义viewstate属性中 5.ProcessPostData();该方法会调用两次, 5.1处理保证了在执行页面加载之前,所有的数据从页面上被读取, 这样页面加载时就可以访问这些数据(将viewstate中的值还原到对应控件中,以及页面的viewstate属性中) 5.2ProcessPostData则是为了使页面加载时新建立的控件中的 数据能够得到处理,两次处理缺一不可 6.OnPreLoad(EventArgs.Empty); 页面预加载事件, 程序员自己对控件属性进行一些修改操作 7.Load()中调用LoadRecursive();递归调用所有页面的PageLoad(); 8.ProcessPostData();第二次调用. 9.RaiseChangedEvents();遍历当前的控件树,找到当前的控件并标记. 10.RaisePostBackEvent(this._requestValueCollection);被标记控件发送回传请求,调用该控件注册的事件 11.OnLoadComplete(EventArgs.Empty); 12.PreRenderRecursiveInternal();检测当前控件是否可见,不可见的话设置标识,用于将来 准备生成请求页面时 不生成该控件的HTML代码,遍历调用子控件的PreRenderRecursiveInternal()方法 13OnSaveStateComplete(EventArgs.Empty); 将服务器控件值以及自定义的viewstate的值通过序列化及base64编码保存到 页面的viewstate属性中. 14.RenderControl(this.CreateHtmlTextWriter(this.Response.Output)); 调用控件集合的RenderControl方法,然后遍历集合调用每个控件中的RenderControl方法,生成请求页面的HTML代码
3.isPostBack原理,是看你每次请求的地址中是否含有__VIEWSTATE 面试题-------------------------------------------------- 1.页面生命周期是什么? 1.1.全局:是页面在服务器端被创建完毕后,按照Page类预先定义的代码的执行过程. 1.2.为什么要有生命周期: 为程序员提供修改控件树属性的通道.(程序员在cs后台页面的方法都注册在生命周期的事件上--通过页面对象的自动事件注册机制) 1.3.aspx页面就是控件(asp.net中有个概念 页面即控件)
画图 从HttpContext-HttpApplication中的PR--请求管道--11至12事件之间执行请求页面的PR()--里面构造控件树--生命周期--render()遍历控件中的HTML代码
2.如果要在Page_Load之前做一些处理怎么办? 需要再Page_Load方法之前,加一个Page_PreLoad()方法,在里面可以进行 预加载处理.
------------------- (重要)缓存机制: --------------------------------------------------------------------------------------------- 待定!!(注意:浏览器再次请求相同页面时,会先到服务器缓存中查找是否存在该页面的缓存,如果存在 在对失效时间进行判断,如果没有失效则返回304,让浏览器到客户端缓存文件中查找.)
页面缓存: 1.当IE浏览器第一次发送页面请求到服务器时,服务器先从缓存中 查找有没有当前的请求页面,如果有的话就直接从缓存中读取 如果没有的话,会先读取数据库,并正常运行页面对象及内部方法 将处理完毕后的响应报文 返回给服务器,服务器将响应报文(包括当前服务器时间)保存到缓存中,同时将响应报文 返回给浏览器(报文头中带着Last-Modified:1:01) 2.当前的IE浏览器再次向服务器发送相同页面请求时,请求报文头中 会包含If-Modified-Since:1:01,此时服务器会将这个时间 加上 设置的缓存失效时间, 与系统当前的时间比较, 如果没有失效的话,直接返回304状态码,让浏览器自己到客户端缓存中取 如果失效的话,就再次到数据库中读取所请求的页面信息返回. 3.当谷歌浏览器在失效时间内请求刚才相同的页面,同样会 先到服务器的缓冲池中查找是否有请求页面的缓存,如果没有,则 同样进行读取数据库,返回响应报文并保存到服务器缓冲池中, 如果查找到对应页面的缓存,则将页面HTML信息返回给浏览器 (在响应报文头中包括缓存的创建时间Last-Modified:1:01), 4.当谷歌浏览器在失效时间内再次访问相同页面时,会在 请求报文头中包含上次获得缓存的事件If-Modified-Since: 1:01, 服务器会在这个时间的基础上加上缓存失效时间, 并与系统当前时间 进行比较,如果没有超过失效时间,则服务器直接返回304状态码 给浏览器,让浏览器自己取缓存信息. 如果缓存失效,服务器同样会先 到服务器缓存中查找请求页面的缓存是否存在,并按照正常流程进行 ,如果缓存池中能够查找到缓存,则直接取缓存中的信息返回给浏览器, 否则,依然进行页面对象及内部方法的处理,生成HTML页面返回响应报文. ------------------------------------------------------------------------------------------- NOTE: 简而言之: 服务器会判断浏览器发来的If-Modified-Since时间与 当前被请求页面的缓存时间的和 是否 大于当前服务器系统时间: A. 如果大于,则代码缓存有效,服务器直接返回304状态吗 B. 如果小于,则代表缓存失效,服务器则先去缓存池,查找当前页面的缓存: b1.如果有,则直接返回缓存的数据给浏览器,并返回此缓存的创建时间 b2.如果没有,则创建页面对象,调用页面代码,最终生成html代码, 保存到缓冲池中,并将此html代码返回给浏览器,同时返回此缓存 创建的时间
---------------- 2.数据源缓存机制 ----------------
3.自定义缓存 Cache类实现了IEnumerable接口,可以看成是一个集合. Cache["key"]=value; 跟Session相似都是存储在服务器中的 3.1.Session 和 Cache的异同点: 相同点: 1.都是保存状态的机制 2.都存在服务器端 3.都是以键值对的形式保存在服务器端 不同点: Cache:当前浏览器所有用户都共有的,共享数据. Session:单个用户使用,相互之间不共享Session数据。 根据浏览器用Cookie保存的SessionId来决定访问的数据。
设置自定义缓存的失效时间: 相对失效时间,按照最后一次访问的时间开始倒计时 Cache.Insert("key",value,null,system.Web.Caching.NoAbsoluteExpiration,new TimeSpan(0,0,15)); 绝对失效时间,按照第一次访问的时间开始倒计时 Cache.Insert("key",value,null,system.Web.Caching.NoAbsoluteExpiration,new TimeSpan(0,0,15)); 缓存:指临时文件的交换区,电脑会把最常用 的文件从存储器里提出来临时放在缓存里.,在Web开发中以空间换时间的机制
4.缓存依赖:(文件缓存依赖,数据库缓存依赖,综合缓存依赖等等) 解决缓存数据(服务端缓存数据)与硬盘数据(客户端缓存文件)不一致的情况 产生的一种机制 可以理解为:实时更新客户端缓存数据的一种机制,保证客户端缓存数据与数据库中数据一致 5.缓存的缺点: 容易产生 <脏数据> ---即当用户第一次访问页面,读取数据库,并将数据存入缓存后, 在该缓存失效前,其他访问都是读取缓存中的数据. 但是如果此期间数据库的数据 发生改变,那么缓存里保存的数据 和 数据库的数据就不一致了! 这就是所谓的缓存脏数据
解决问题 : 使用 缓存依赖 可以解决这个 脏数据问题. 即:启用缓存依赖机制,此机制会负责检测物理数据是否发生改变,一旦发生改变则去缓存中删除 对应的缓存(键值对)
数据库缓存依赖 缓存检测服务,按照配置文件,每个15秒钟就去数据库查询缓存依赖记录版本表, 根据Sql缓存依赖里提供的表名来查询,如果发现该记录的版本号发生改变, 则立即销毁服务器缓存中对应的缓存键值对.
Note: 浏览器端缓存机制 1.当浏览器使用get方式请求服务器时,浏览器会先到浏览器端临时文件夹中,根据页面名称 查找看是否有缓存版本,如果有,则直接读取,不在发送请求到服务器 2.当浏览器使用Post方式请求服务器时,浏览器会直接发送请求报文到服务器,而不去检查 浏览器端临时文件夹. 当时,当请求报文中包含If-Modified-Since时间的时候,服务器会根据 该时间判断服务器端缓存是否失效,如果没有失效,则返回304状态码给浏览器,浏览器则读取缓存.
7.服务器为什么会根据If-Modified-Since来生成304状态码? 1.服务器就知道浏览器端有缓存 2.服务器就不再读取服务器端的缓存 3.服务器生成的响应报文中就不必包含报文体(页面html代码),从而减轻了回传的数据量 4.此机制也可以保证 浏览器端页面缓存和服务器端的缓存一致
8.缓存清除方式: 1.获得缓存枚举器 GetEnumerator() 2.遍历枚举器 3.将每个缓存项的Key保存到集合汇总 4.根据所有的key来清空缓存 Remove