ASP.NET网页请求以及处理全过程(反编译工具查看源代码)
本文是自己查看源码后的个人总结,不保证其准确性。大家可作为参考。
浏览器和服务器之间的通信。
当敲一个域名到浏览器上面,然后回车的时候,如:http://www.baidu.com/index.aspx
浏览器会按照HTTP协议的语法生成相应的请求报文。
浏览器检查本机是否保存了http://www.baidu.com/index.aspx域名对应的服务器IP地址。如果没有,则发送请求到所在城市网中最近的DNS服务器(域名解析服务器),它会根据我们发送来的域名查询到该域名对应的服务器IP地址,并发送回浏览器。
浏览器DNS服务器获得了这个域名所对应的服务器电脑的IP然后在庞大的互联网中找到这个对应的服务器
HTTP协议规定服务器软件如(iis)使用的默认端口是80端口,也就是说浏览器默认的将HTTP请求报文发送到对应服务器的80端口。
服务器接受到浏览器发送到的HTTP请求报文(具体报文用httpwatcher查看)。
下面是发送到百度的请求报文:
服务器分析请求报文中的路径和文件名,在服务器找到这个文件。
如果是CSS和html,js,图片等文件就直接在服务器上面读取这个文件发送给浏览
器客户端。
下面是对ASP.NET动态页面的处理
当服务器IIS发现你请求的页面是动态页面,他发现他自己处理不了。
打开IIS,会发现里面有个处理程序映射
,也就是说IIS会将我们的.aspx后缀的文件交给对应的处理程序(aspnet_isapi.dll)。这里简称ISAPI。
ISAPI就会将请求交给.NET framework。
再有ISAPI将请求交给ASP.NET,也就是一个名为aspnet_wp.exe的工作进程aspnet_wp.exe就调用FrameWork里的类 ------- ISAPIRuntime。
下面是用反编译工具来分析的这个类ISAPIRuntime(System.Web.Hosting)
看到这个方法,就会想到了垃圾回收。
其实这不是重点。重点是
这个processrequest方法
点击这个方法进去
首先会创建一个ISAPIWorkerRequest的对象wr,将请求报文封装到wr中
然后调用这个类的CreateWorkerRequest方法实例化这个对象
进入这个方法
这个方法会根据当前的IIS版本创建不同的对象
再回到ProcessRequest方法
接着就会调用HttpRuntime(System.Web)的ProcessRequestNoDemand方法。将wr传进去
进入这个方法
在这个方法的最后会调用
ProcessRequestNow方法。处理请求
这个方法有调用了另一个方法。进去
这里就会发现一个熟悉的东西,HttpContext(上下文对象)
这个方法会根据上面创建的ISAPIWorkerRequest对象wr(封装了请求报文)创建HttpContext。如果创建出错,就会返回一个400的错误。
判断是否是第一次请求之前
(如果是第一次请求,就设置当前的时间为第一次请求的起始时间。初始化第一次请求。设置第一次请求为false)
初始化Response.
当httpwriter为空的时候,就创建。可以看到,context.response中有2个写出器
一个是httpwriter,一个是textwriter
然后通过HttpApplicationFactory创建一个HttpApplication对象(此对象负责真正处理页面对象的创建和执行,先在httpapplication池中看又没有这个对象,没有就new一个)
下面打开HttpApplication这个类
在这里面最重要的就是这25个事件。其中有19个事件开放给我们使用。
1,BeginRequest
HTTP管道开始处理请求时,会触发BeginRequest事件
2-3,AuthenticateRequest,PostAuthenticateRequest
ASP.NET先后触发这两个事件,使安全模块对请求进行身份验证,。
4-5,AuthorizeRequest,PostAuthorizeRequest
ASP.NET先后触发这两个事件,使安全模块对请求进程授权
6-7,ResolveRequestCache,PostResolveRequestCache
ASP.NET先后触发这两个事件,以使缓存模块利用缓存的直接对请求直接进程响应(缓存模块可以将响应内容进程缓存,对于后续的请求,直接将缓存的内容返回,从而提高响应能力)。
8,PostMapRequestHandler
对于访问不同的资源类型,ASP.NET具有不同的HttpHandler对其进程处理。对于每个请求,ASP.NET会通过扩展名选择匹配相应的HttpHandler类型,成功匹配后,该实现被触发
9-10,AcquireRequestState,PostAcquireRequestState
ASP.NET先后触发这两个事件,使状态管理模块获取基于当前请求相应的状态,比如SessionState
11-12,PreRequestHandlerExecute,PostRequestHandlerExecute
ASP.NET最终通过一请求资源类型相对应的HttpHandler实现对请求的处理,在实行HttpHandler前后,这两个实现被先后触发
13-14,ReleaseRequestState,PostReleaseRequestState
ASP.NET先后触发这两个事件,使状态管理模块释放基于当前请求相应的状态
15-16,UpdateRequestCache,PostUpdateRequestCache
ASP.NET先后触发这两个事件,以使缓存模块将HttpHandler处理请求得到的相应保存到输出缓存中
17-18,LogRequest,PostLogRequest
ASP.NET先后触发这两个事件为当前请求进程日志记录
19,EndRequest
整个请求处理完成后,EndRequest事件被触发
在第8个事件创建被请求页面类的对象,并转换成Ihttphandler接口类对象。,
在9-10事件中会接受浏览器发送过来的sessionid,并且根据此值到服务器的session池中找到相对应的session对象,并将它赋值给页面类对象的session属性。
在第11到12事件之间执行页面类的processrequest方法。
下面是状态保持:session,cookie viewstate。写完状态保持再仔细将在11到12事件中具体做了什么事情
Cookie是保存在浏览器端的,cookie有两种状态,一种是保存在客户端电脑的内存中,当访问页面的时候创建的cookie(也就是没有设置过期时间的cookie)。还有一种是设置了过期时间为正的cookie,是保存在浏览器所对应的cookie文件夹中的。设置cookie前,浏览器发送请求到服务器,服务器要对该浏览器设置cookie,所以就发送一个cookie到浏览器,保存在客户端的内存或者硬盘中。当设置了cookie后,每次请求页面都会把cookie发送到服务器
服务器通过读取cookie得知你的相关信息然后进行相应的操作。
Session是依赖于cookie实现的。不同的是session是保存在服务器端的。
例如,当我们登陆的时候,服务器那边会给我们设置一个session保存在服务器端,然后会产生一个sessionid发送到浏览器端,浏览器这边存储这个sessionid,当你再请求别的页面的时候,浏览器就会将这个sessionid发送到服务器。,服务器根据从浏览器发送过来的sessionid自动从服务器的session池中找到与这个sessionid想对应的session对象并赋值给当前页面对象的session属性。
如果浏览器禁用了Cookie的话,那服务器也可以通过将sessionId保存在url中来完成sessionid在浏览器和服务器间的传递。(需要设置配置文件里的 sessionState节点的 cookieless="autodetect")
<sessionState cookieless="AutoDetect"></sessionState>
Viewstate:页面的viewstate属性实际上就是获取了浏览器提交过来的一个名位__VIEWSTATE的隐藏域里面的值。
使用viewstate必须要有一个runat=“server”的表单
在页面类对象执行processrequest方法的时候,先创建控件树,然后通过执行loadstate方法,将请求报文中的名为__VIEWSTATE反base64编码然后进行序列化,最终还还原成集合,再将其中属于程序员自己添加的viewstate里面的键值对还原到页面对象的viewstate属性中,然后再执行page_load。,然后执行savestate将数据保存到viewstate属性中。
那么在第11到12之间中执行了页面类对象的processrequest方法,到底做了什么呢。
1, 调用父类的processrequest方法,在此方法中父类调用父类的FrameworkInitialize()方法,但因为被页面类重写了,所以执行的是当前页面类的FrameworkInitialize()方法。在中间调用了_buildControlTree
2, 打造控件树
前台页面类。
前台页面类继承自后台页面类。
后台页面类继承自page
Templatecontrol继承自control
在coltrol类中
在中间有一个control集合
也就是说我们的前台页面类根据继承关系包含了一个控件集合。
再来到前台页面类。
,在最后面发现一个ProcessRequest方法。
,进去。
Bulidcontroltree开始打造控件树。
前台类继承后台类
litralControl包含html代码的第一段。
Htmlhead-htmltitle......
_BuildControlTree这个方法会将前台的所有代码封装起来,根据不同的标签封装成不同的控件对象。
3, 执行页面生命周期
1. Page_Init();
2. Load ViewState and Postback data;
3. Page_Load();
4. Handle control events;
5. Page_PreRender();
6. Page_Render();
7. Unload event;
8. Dispose method called;
阶段 |
说明 |
页请求 |
页请求发生在页生命周期开始之前。用户请求页时,ASP.NET 将确定是否需要分析和编译页(从而开始页的生命周期),或者是否可以在不运行页的情况下发送页的缓存版本以进行响应。 |
开始 |
在开始阶段,将设置页属性,如 Request 和 Response。在此阶段,页还将确定请求是回发请求还是新请求,并设置 IsPostBack 属性。此外,在开始阶段期间,还将设置页的 UICulture 属性。 |
页初始化 |
页初始化期间,可以使用页中的控件,并将设置每个控件的 UniqueID 属性。此外,任何主题都将应用于页。如果当前请求是回发请求,则回发数据尚未加载,并且控件属性值尚未还原为视图状态中的值。 |
加载 |
加载期间,如果当前请求是回发请求,则将使用从视图状态和控件状态恢复的信息加载控件属性。 |
验证 |
在验证期间,将调用所有验证程序控件的 Validate 方法,此方法将设置各个验证程序控件和页的 IsValid 属性。 |
回发事件处理 |
如果请求是回发请求,则将调用所有事件处理程序。 |
呈现 |
在呈现之前,会针对该页和所有控件保存视图状态。在呈现阶段中,页会针对每个控件调用 Render 方法,它会提供一个文本编写器,用于将控件的输出写入页的 Response属性的 OutputStream 中。 |
卸载 |
完全呈现页并已将页发送至客户端、准备丢弃该页后,将调用卸载。此时,将卸载页属性(如 Response和 Request)并执行清理。 |
4, 调用页面类的Render方法生成html代码。
上面貌似很乱。下面整理一下。
1, 浏览器请求一个动态页面。IIS发现自己不能处理,将请求转给映射表。
2, 映射程序里面aspx页面对应的是aspnet_isapi.dll,于是就将请求转给ISAPI
3, 请求报文通过ISAPIRuntime交给了HttpRuntime。
4, 在HttpRuntime里面创建了ISAPIWorkerRequest的对象wr,将请求报文封装到wr中。再通过一系列方法创建HttpContext上下文对象,里面包含HttpRequest和HttpResponse。
5, 然后通过HttpApplicationFactory创建一个HttpApplication对象(此对象负责真正处理页面对象的创建和执行,先在httpapplication池中看又没有这个对象,没有就new一个)
6, 在httpapplication请求管道中调用19个标准的处理事件。
在第8个事件中创建被请求的页面类对象
在第9-10事件中接受浏览器发送过来的sessionid,并且根据此值到服务器的session池 中找到相对应的session对象,并将它赋值给页面类对象的session属性。
第11-12事件执行页面类的processrequest方法。打造控件树,执行页面生命周期,调用页面类中所有控件对象的Render方法,生成html代码
7, 将html代码返回给浏览器。
转载:https://www.cnblogs.com/poorpan/archive/2011/09/25/2190308.html
ASP.NET网页请求以及处理全过程(反编译工具查看源代码)的更多相关文章
- 工欲善其事,必先利其器 软件工具开发关键词 protractor自动化测试工具 RegexBuddy正则 CodeSmith,LightSwitch:代码生成 CheatEngine:玩游戏修改内存值必备神器 ApkIDE:Android反编译工具 Reflector:反编译dll动态链接库
工欲善其事,必先利其器 本文版权归翟士丹(Stan Zhai)和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利. 原文地址:http ...
- ILSpy反编译工具的使用
以前一直使用reflector来查看.net类库的一些信息,不过,自2011年2月份开始,reflector就开始转向收费软件了,所以爱好免费软件的开发者们转而开发自己的反编译软件.于是ILspy就因 ...
- .net程序反编译工具(ILSpy)
ILSpy是SharpDevelop小组的反编译工具,ILSPY这个开源工具的目的就是代替reflector的,它可以反编译出比reflector更好的C#代码. PC官方版 C#反编译工具ilspy ...
- apk反编译工具
反编译工具: apktool:资源文件获取,可以提取出图片文件和布局文件进行使用查看 dex2jar:将apk反编译成Java源码(classes.dex转化成jar文件) jd-gui:查看APK中 ...
- eclipse安装反编译工具
身为一名程序员来说,日常最常做的就是编写代码和查看别人写好的源代码了,有时候打开别人写的class文件发现根本不是自己想要的,所以给大家介绍一种eclipse中反编译class文件的工具. 第一步:下 ...
- .net混淆、反编译工具调查
常用的工具列表[比较常见的] 混淆器.加密 Dotfuscator VS默认带的工具,不过是个社区版 强度不大 dotNET Reactor 使用了NativeCode 和混淆的形式 Xenocode ...
- Android反编译工具的使用-Android Killer
今天百度搜索“Android反编译”搜索出来的结果大多数都是比较传统的教程.刚接触反编译的时候,我也是从这些教程慢慢学起的.在后来的学习过程中,我接触到比较方便操作的Android反编译.在这,我将使 ...
- Eclipse反编译工具Jad及插件JadClipse配置
Jad是一个Java的一个反编译工具,是用命令行执行,和通常JDK自带的java,javac命令是一样的.不过因为是控制台运行,所以用起来不太方便.不过幸好有一个eclipse的插件JadClipse ...
- .net 反编译工具
遇到一个需求,做一个专门访问自己网站的浏览器给用户使用,这个浏览器提供登录功能.此时是一个安装在客户端的exe程序,做登录验证要用到webservice,不能将验证逻辑写入exe中,否则客户端可以利用 ...
随机推荐
- mybatis 逆向工程使用姿势不对,把表清空了,心里慌的一比,于是写了个插件。
使用mybatis逆向工程的时候,delete方法的使用姿势不对,导致表被清空了,在生产上一刷新后发现表里没数据了,一股凉意从脚板心直冲天灵盖. 于是开发了一个拦截器,并写下这篇文章记录并分享. 这锅 ...
- 用于实现tab页签切换页面的angular路由复用策略
使用场景 打开菜单页面的时候,出现对应页面的页签.切换页签,原来的页面信息状态保留,关闭页签则保留的信息删除.使用路由复用策略,保存路由快照.实现效果如图所示 实现过程 概述: 1.在app.modu ...
- javaweb之Servlet,http协议以及请求转发和重定向
本文是作者原创,版权归作者所有.若要转载,请注明出处. 一直用的框架开发,快连Servlet都忘了,此文旨在帮自己和大家回忆一下Servlet主要知识点.话不多说开始吧 用idea构建Servlet项 ...
- 调用webservice接口,报错:(十六进制值0x01)是无效的字符
#事故现场 调用webservice接口,报错:(十六进制值0x01)是无效的字符. 如图: 意思是webservice返回的信息中包含无效的字符,无法解析成xml: #分析 使用postman向we ...
- Magic Line【坐标点排序方法】
Magic Line 题目链接(传送门) 来源:牛客网 题目描述 There are always some problems that seem simple but is difficult to ...
- TensorFlow从0到1之常量、变量和占位符详解(6)
最基本的 TensorFlow 提供了一个库来定义和执行对张量的各种数学运算.张量,可理解为一个 n 维矩阵,所有类型的数据,包括标量.矢量和矩阵等都是特殊类型的张量. TensorFlow 支持 ...
- spring Cloud网关之Spring Cloud Gateway
Spring Cloud Gateway是什么?(官网地址:https://cloud.spring.io/spring-cloud-gateway/reference/html/) Spring C ...
- 如何从OutLook正确取得定期会议的时间?(待解决)
背景: 用Microsoft.Office.Interop.Outlook取得日历项,然后根据业务要求筛选. 现象: 如果是定期会议,使用AppointmentItem.Start/End取得的是该定 ...
- 原来你是这样的BERT,i了i了! —— 超详细BERT介绍(一)BERT主模型的结构及其组件
原来你是这样的BERT,i了i了! -- 超详细BERT介绍(一)BERT主模型的结构及其组件 BERT(Bidirectional Encoder Representations from Tran ...
- 性能测试之JVM的故障分析工具VisualVM
VisualVM 是随JDK一同发布的jvm诊断工具,通过插件可以扩展很多功能,插件扩展也是其精华所在. 提供了一个可视界面,用于在Java应用程序在Java虚拟机上运行时查看有关Java应用程序的详 ...