asp.net 请求输入到输出的全过程及httpHandler和htt
最近我深入研究了httpHandler和HttpModuler,虽然还没有完全理解底层操作,但我明白了许多关于一个请求在IIS中的处理过程。对此感兴趣的朋友们,我强烈推荐你们也去了解一下。
我主要参考了Fish li的文章,他的讲解非常深入且实用。尽管我作为一个普通的开发者并不能完全理解他文章中的高级技术内容,但我依然从中受益匪浅。
在了解IIS底层操作之前,我曾误以为.Net的类库都是设计者自行设计的,没有考虑到普通开发者的学习难度。但深入了解后,我发现每个.Net的类都是对应现实中的一种对象。例如,在Mvc3中的路由就包括了RouteData和HttpContext。只有了解iis的触发过程,我们才能真正理解这些类的用途和为什么要这样设计。
接下来,我想分享一下我对IIS底层工作的理解。虽然我的技术并非顶尖,但我将尽力用通俗易懂的语言来描述。
在IIS 6中,一个请求的处理过程大致如下:
由于我们现在主要使用的是MVC3,所以我将按照MVc3的生命周期来描述一个请求从开始到结束的全过程。
用户通过浏览器输入如localhost/home/index的地址,浏览器会发送一个请求到服务器的IIS进行处理。在操作系统中,有一个名为http.sys的系统文件,它负责监视请求的到来。也就是说,用户发出的请求首先接触到的是http.sys,它是一个在操作系统内核模式下运行的系统文件,处理速度非常快。
在http.sys接收到请求后,请求会被传送到IIS,也就是真正的处理请求的操作系统组件。IIS接收到用户请求后,会通过映射文件由asp_iisapi.dll(IIS扩展)根据文件扩展名选择对应的应用程序。对于MVC来说,由于没有文件扩展名,那么程序是如何匹配的呢?其实有两种处理方式:
1. 在路由表中添加一个虚拟的扩展名来“欺骗”IIS。
2. 在IIS配置文件中不选择确认文件存在,让IIS根据没有文件扩展名的文件路径来进行处理。
接下来,请求会进入.Net框架,由.Net框架处理请求。在这个过程中,会经过一些步骤的处理。大家应该记得在Web Form中有很多事件,如Page_load、Page_Render等,这些事件的执行顺序是依次进行的,不会混乱。.Net框架是如何保证这些事件的顺序执行的呢?这就需要提到今天的主角——HttpModule。我们可以把它称为http请求的过滤器,因为它会在任何请求中执行。除了静态文件或其他没有配置为让IIS扩展和.Net框架处理的请求文件,因为对于这些请求,IIS会找到对应的文件然后直接输出给浏览器。
关于HttpModule的具体使用,许多专家都有详细的解释,我就简单描述一下他们可能没有提到的一些知识点。既然HttpModule可以作为一个过滤器,那么我们可以在任何一个HttpModule中终止当前请求的执行,进行身份认证、检查文件的访问权限等操作。要自定义HttpModule扩展,只需要让我们的类实现IHttpModule接口,在IHttpModule接口中的Init方法就是我们自定义扩展的入口,我们可以在其中定义自己的处理操作。
Init方法接受的HttpApplication参数代表了ASP.NET应用程序中的所有应用程序对象通用的方法、属性和事件。这个类是我们在global.asax文件中定义的应用程序的基类。通过对HttpApplication的使用,我们可以在整个应用程序生命周期中处理各种事件,从而实现对请求的全面控制和管理。在ASP.NET架构中,HttpApplication类的实例扮演着至关重要的角色。这些实例并非由用户直接创建,而是在ASP.NET基础设施中诞生的。每一个HttpApplication实例在其生命周期内,负责处理多个请求,但每次仅专注于一个请求的处理。这种设计使得成员变量能够存储针对每个请求的独特数据。
当我们谈论到应用程序池的概念时,我们可能会联想到在IIS(Internet Information Services)中创建的新应用程序。而这些应用程序背后,其实正是HttpApplication对象的集合。每个请求都有一个对应的HttpApplication对象,全程负责其执行过程。这个对象中包含了请求所需的所有参数值,例如Response、Request、Cache等.Net常用的对象。更令人兴奋的是,通过这个对象,我们还可以访问到web.config中定义的所有Module扩展。可以说,HttpApplication对象伴随着请求的全过程。
那么,当Module扩展需要传递一个HttpApplication对象作为参数时,是谁创建了这个对象呢?答案是HttpRuntime类。从字面意思上理解,HttpRuntime代表了HTTP的运行时环境。当IIS将请求的数据准备好后,会通过HttpRuntime调用HttpApplicationFactory的Create()方法,创建一个HttpApplication对象,并传递相应的参数值。这个对象会进一步传递到Module扩展中。
经过Module扩展的过滤后,请求会进入到真正的处理阶段,这个阶段的主角是HttpHandler。虽然我们对HttpHandler可能有些陌生,但一定对.Net中的一般处理程序(ashx文件)不陌生。一般处理程序背后,其实就是实现了IHttpHandler接口的codeBehind文件。换句话说,只要实现了IHttpHandler接口中的方法,就定义了一个Handler扩展。
值得注意的是,HttpHandler作为处理者出现,而非过滤者。Handler会有输出结果。如果在Handler中需要使用Session,那么就需要继承IRequiredSessionState接口,或者添加IReadOnlySessionState接口。这样,在操作Session时就不会出现错误。在Handler中,我们可以进行各种操作,如生成图片水印、实现防盗链、文件输出压缩以及编码等。HttpApplication及其相关组件在ASP.NET中构建了一个高效、灵活的请求处理机制。深入理解MVC与Web技术:从请求到响应的旅程
Web服务及一般处理程序,它们实际上都是Handler的高级实现方式,代表了Handler的扩展操作。当我们谈论MVC时,路由Route作为Mvc中的一个核心组件,在整个请求过程中起着至关重要的作用。
当IIS通过扩展选择适当的处理程序来处理请求时,路由机制开始发挥作用。它根据路由配置分析路径中的ControllerName和ActionName,以及相应的参数值。这些参数被存储在RouteData中,而RouteTable.Routes则是一个路由集合。RouteData与HttpContext上下文共同组成RequestContext对象,这在MVC编程中经常用到。
.Net框架会根据RequestContext对象的值来匹配程序中的Controller和Action。通过调用ControllerDescriptor执行Controller,生成Controller的对象,然后通过ActionInvoke方法来执行具体的Action。
Action执行完毕后,返回对应的视图,此时整个请求在.Net框架中的处理就告一段落。输出结果会经过Module扩展处理,然后返回到IIS,再通过Http.sys响应到用户浏览器上。值得注意的是,一个请求会两次经过Module扩展,这也是我们在Web Form中可以定义开始事件和完成事件的原因。
回顾一下,一个用户发起的请求通过http.sys传输到IIS,再经过asp_iisapi.dll,接着到对应的处理程序,然后是Module和Handler。在这个过程中,aspx文件作为一个单独的handler在编译时被编译成一个类,这个类继承自Page,而Page又继承自IHttpHandler接口。这验证了aspx文件的执行是在Handler执行时触发的。
尽管一个小小的HTTP请求背后涉及的知识非常广泛,但作为程序员,我们应该对这个请求模型了如指掌。在这个Mvc时代,让我们拥抱新技术,深入理解并应用这些知识。
我是小兵,虽无太多发言权,但我会尽力按照我的理解来分析大牛们的技术。希望大家在掌握这些基础知识的也能不断新技术,不断提高自己的技能水平。
平面设计师
- asp.net 请求输入到输出的全过程及httpHandler和htt
- thinkphp3.x中session方法的用法分析
- jquery获取select,option所有的value和text的实例
- 在asp.net中KindEditor编辑器的使用方法小结
- vue 登录滑动验证实现代码
- JS数字千分位格式化实现方法总结
- AngularJS点击添加样式、点击变色设置的实例代码
- 微信小程序 按钮滑动的实现方法
- 利用Jquery实现几款漂亮实用的时间轴(附示例代码
- laravel5.1框架基础之Blade模板继承简单使用方法分
- 深入浅析knockout源码分析之订阅
- Vue-cli创建项目从单页面到多页面的方法
- 详解PHP发送邮件知识点
- windows下vue-cli导入bootstrap样式
- php的RSA加密解密算法原理与用法分析
- jquery表单提交带错误信息提示效果