这篇文章是从我的 github 博客 lxconan.github.io 导入的。

这是这个系列的第三篇了。前两篇文章请参见:

这一篇仍然是原理上的东西,不涉及代码。我保证从下一篇开始,我们就开始写代码了。所以还请忍耐。

ASP.NET 的请求处理流程

在这篇文章中,我们讨论的问题是 ASP.NET 对 HTTP 请求的处理流程。但是这个流程并不止限于 ASP.NET。许许多多的 Web Server 都是采用了相似的处理流程。这个流程就像是张三在上课的时候给他的好朋友(或者死对头)(我们叫他:赵六)传纸条。首先我假定张三很尊重老师的,不想伤害他脆弱的心灵,于是他无法把纸条直接传到赵六的手中,他必须先把纸条交给离他最近的同学手中,然后依次传递。我们不妨假定这个过程必须经过这几个人:

张三 --> 李四 --> 王五 --> 赵六

那么不难想到,纸条回来的路径也需要依次反向的经过相同的人。也就是

赵六 --> 王五 --> 李四 --> 张三

那么传纸条开始,首先张三写了一张纸条,其内容是:(少儿不宜,故隐去)。纸条送到了李四的手中,李四是一个有理想有道德的青年,于是拒绝继续传递下去。张三无奈,只得又写了一张新的。其内容是:“下课后是否去一起吃饭?”。纸条送到了李四的手中,李四看后把纸条递给了王五;王五看后将纸条递给了赵六。赵六看后,欣然写到:“好滴”,又把纸条交到了王五手中;王五接到纸条不觉有些心动,于是在纸条上也添了一笔:“我也去!”,就把纸条交给了李四;李四直接将纸条传回张三手中,于是张三看到了如下的内容:“好滴。我也去(王五)”。

我们不妨将张三的行为视为张三向赵六发出的请求。而在请求传递的过程中经过了李四和王五。整个过程一共涉及到了两种角色:第一种角色是赵六,他是请求到达的终结点,也是创建响应的人;而第二种角色就是李四和王五,他们在整个过程中都可以看到请求和响应的内容,并可以对请求或者响应进行过滤或者更改。

在 ASP.NET 中,这两种角色分别称之为:Http Handler 以及 Http ModuleHttp Handler 作为 Request 处理的终结点存在,并负责处理请求以及生成响应。几乎所有的高级 Web 特性,例如页面的生成、MVC 都是 Http Handler。而相应的 Http Module 作为请求传递的中间环节,主要对 Request/Response 进行过滤和修饰。常见的任务例如身份验证,Session 管理都是使用 Http Module 进行处理的。

不难理解,每一个 Request 最多只可能有一个 Http Handler 对其进行处理;而每一个 Request 可能会有多个 Http Module 对其进行过滤或者修饰。

在 ASP.NET 中,Http Handler 实现了 IHttpHandler 接口而 Http Module 实现了 IHttpModule 接口。

观察 Http Handler 和 Http Module

如何观察我们的 Web App 搭建了怎样的处理流程呢?

在 IIS 中观察

第一种方式是在 IIS 中观察,这种方式非常简单实用。首先打开 IIS 管理器,选择需要观察的 Web App 或者某一个虚拟目录。之后,在右侧的“处理程序映射”中可以看到所有启用了的 Http Handler。例如,我的 Web App 启用了如下的 Http Handler

  • 对于 \* 类型的请求,使用 System.Web.Handlers.TransferRequestHandler 进行处理(这个 Http handler 也是 ASP.NET MVC 的基础);
  • 对于 *.aspx 类型的请求,使用 System.Web.UI.PageHandlerFactory 进行处理(这个 Http handler 是 WebForm 的基础);
  • 对于 *.cshtml 类型的请求,使用 System.Web.HttpForbiddenHandler 进行处理(因为客户端是不允许访问服务端代码的);
  • ……

至于 Http Module,可以在 “模块” 中进行观察。在“分组依据”中选择“托管模块”就可以观察到 ASP.NET 注册的 Http Module 了。

在 Powershell 中观察

第二种方式是在 Powershell 中使用 IIS Extension 进行观察。这个非常符合我们的胃口,也为 Automation 提供了可能。在观察之前,请确认你已经安装了 Powershell 的 WebAdministration 模块。然后以管理员身份启动 Powershell,在 Powershell 中进行如下输入:

PS C:\> IIS:
PS IIS:\> cd Sites
PS IIS:\Sites> cd Default # Suppose we have a website named 'Default'
PS IIS:\Sites\Default>

此时我们就进入了 Default Website 的虚拟路径。我们可以使用 Get-WebHandler 查看当前虚拟路径下的 Http handler 设置。

PS IIS:\Sites\Default> Get-WebHandler
Name Path Verb Modules
---- ---- ---- -------
WebDAV * PROPFIND,PROPPATCH,MKCOL,P... WebDAVModule
ISAPI-dll *.dll * IsapiModule
AXD-ISAPI-4.0_64bit *.axd GET,HEAD,POST,DEBUG IsapiModule
PageHandlerFactory-ISAPI-4... *.aspx GET,HEAD,POST,DEBUG IsapiModule
SimpleHandlerFactory-ISAPI... *.ashx GET,HEAD,POST,DEBUG IsapiModule
WebServiceHandlerFactory-I... *.asmx GET,HEAD,POST,DEBUG IsapiModule
HttpRemotingHandlerFactory... *.rem GET,HEAD,POST,DEBUG IsapiModule
HttpRemotingHandlerFactory... *.soap GET,HEAD,POST,DEBUG IsapiModule
... ...

为了查看 ASP.NET 注册的 Http Module 我们可以使用如下的命令:Get-WebManagedModule

PS IIS:\Sites\Default> Get-WebManagedModule
Name Precondition Type
---- ------------ ----
UrlRoutingModule-4.0 managedHandler,runtimeVersionv4.0 System.Web.Routing.Url...
ScriptModule-4.0 managedHandler,runtimeVersionv4.0 System.Web.Handlers.Sc...
OutputCache managedHandler System.Web.Caching.Out...
Session managedHandler System.Web.SessionStat...
WindowsAuthentication managedHandler System.Web.Security.Wi...
FormsAuthentication managedHandler System.Web.Security.Fo...
DefaultAuthentication managedHandler System.Web.Security.De...
RoleManager managedHandler System.Web.Security.Ro...
UrlAuthorization managedHandler System.Web.Security.Ur...
FileAuthorization managedHandler System.Web.Security.Fi...
AnonymousIdentification managedHandler System.Web.Security.An...
Profile managedHandler System.Web.Profile.Pro...
UrlMappingsModule managedHandler System.Web.UrlMappings...

在 web.config 文件中观察

上一篇中,我们介绍了 web.config 文件是有一种继承体系的。那么我们可以在这个体系涉及的各个文件中查找 Http handler 以及 Http Module 的配置。

Http handler 的配置在 .config 文件的 <system.webServer><handlers> 元素下。例如,我们可以在 IIS 的 applicationHost.config 文件中发现如下的 HTTP handler 的映射信息:

<system.webServer>
<handlers accessPolicy="Read, Script">
<add
name="ExtensionlessUrlHandler-Integrated-4.0"
path="*."
verb="GET,HEAD,POST,DEBUG"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />
... ...
</handlers>
</system.webServer>

Http Module 是配置在 <system.webServer><modules> 下。例如,我们可以在 IIS 的 applicationHost.config 文件中发现如下的 Http Module 信息:

<system.webServer>
<modules>
... ...
<add
name="OutputCache"
type="System.Web.Caching.OutputCacheModule"
preCondition="managedHandler" />
... ...
</modules>
</system.webServer>

这一篇的介绍就到这里,从下一篇开始我们将开始尽可能的构造自动化部署脚本。

ASP.NET MVC 从零开始 - 请求处理的更多相关文章

  1. ASP.NET MVC 从零开始 - 自动化部署(其二)

    这篇文章是从我的 github 博客 http://lxconan.github.io 导入的. 这是这个系列的第五篇了,前四篇请参见: ASP.NET MVC 从零开始 – Create and R ...

  2. ASP.NET MVC 从零开始 - 自动化部署(其一)

    本文是从我的 github 博客 http://lxconan.github.io 导入的. 这是这个系列的第四篇了,前三篇请参见: ASP.NET MVC 从零开始 – Create and Run ...

  3. ASP.NET MVC 从零开始 - create and run

    这篇文章是从我的 github 博客 http://lxconan.github.io 导入的. 如果你想用 ASP.NET MVC 创建一个网络应用,那么你可以搜到很多的文章.但是没有多少文章告诉你 ...

  4. ASP.NET MVC 从零开始 - Web.config

    这篇文章是从我的 github 博客 http://lxconan.github.io 导入的. 在上一篇中,我们从零开始创建了一个非常简单的 ASP.NET MVC 应用程序.接下来,你是不是期望我 ...

  5. ASP.NET MVC的请求处理流程

    (1)用户打开浏览器,在地址栏输入某个网址URL并回车,浏览器便开始向该URL指向的服务器发送HTTP请求(一般是GET方式).(2)服务器端的网站服务系统(IIS)接收到该请求,先检查自己是否认识该 ...

  6. 为什么要坚持用ASP.NET MVC!(②)

    尽管ASP.NET MVC架构和Web Form架构区别很大,但是还是有很多共同之处.毕竟它们都是以ASP.NET API与.NET框架为基础构建的.比较一下ASP.NET MVC和Web Form框 ...

  7. WebForm和Asp.Net MVC的理解

    我对WebForm和Asp.Net MVC的理解   比较WebForm和Mvc的请求处理方式 首先简单了解一下Asp.Net中怎么对页面进行请求处理的: 在管道的第7-8个事件之间,有一个MapHt ...

  8. 在ASP.Net MVC 中如何实现跨越Session的分布式TempData

    Hi,guys!Long time no see! 1.问题的引出 我相信大家在项目中都使用过TempData,TempData是一个字典集合,一般用于两个请求之间临时缓存数据或者页面之间传递消息.也 ...

  9. 笨鸟先飞之ASP.NET MVC系列之过滤器(01过滤器简介)

    过滤器 什么是过滤器? 过滤器(Filter) 主要的作用大致可以理解为把我们的附加逻辑注入到MVC框架的请求处理. 在ASP.NET MVC的请求处理中一种有19个管道事件分别是 BeginRequ ...

随机推荐

  1. EXT.NET 使用总结(3)--动态图表

    动态生成雷达图--Radar 效果图: aspx页面代码: <ext:Panel ID="ResultPanel" Border="true" runat ...

  2. 控制台查看原生sql

    情况:当tomcat运行时,项目运行过程中,控制台没有打印出原生sql语句: 解决办法如下: 在 META-INF  文件夹下,查找 persistence.xml 这个文件(这里注意可能一个项目不止 ...

  3. nodejs复习02

    process 这个模块是单线程的,无法完全利用多核CPU 基本信息 //程序目录 process.cwd(); //应用程序当前目录 process.chdir('/home'); //改变应用程序 ...

  4. 如何解决插入Oracle数据中文为乱码问题

    1.首先,Oracle查询编码:select * from v$nls_parameters;//看看是否GBK 2.如果是用Servlet或者别的,插入数据之前输出一下,看看是否乱码.比如: doP ...

  5. vim配置及快捷键

    vim+python http://codingpy.com/article/vim-and-python-match-in-heaven/ vim+c++ http://jikaichen.com/ ...

  6. 使用VisualVM检测

    下载 https://visualvm.github.io/ 检测远程服务器 转自:http://blog.csdn.net/yangkangtq/article/details/52277794 授 ...

  7. ACM: Gym 101047E Escape from Ayutthaya - BFS

    Gym 101047E Escape from Ayutthaya Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I6 ...

  8. [Protobuf] Mac系统下安装配置及简单使用

    Mac下Protobuf安装 Protobuf源码Github地址: https://github.com/google/protobuf 配置环境教程: https://github.com/goo ...

  9. 如何删除 eclipse debugger 下不用的Java Application

    问题描述:之前写了几个 main 函数 用于测试,现在删除掉了 但是debugger下还存在,看着不爽,想删掉 解决方案: 1.项目--右键 2.删掉就可以了

  10. sql2000分享 批量建表dev_编号

    批量建表dev_3970000000014到dev_3970000000035 declare @i bigint declare @j int ) ) ) ) set @sql = '' set @ ...