从Asp .net到Asp core (第一篇)《回顾Asp .net生命周期与管道机制》

从2016年微软收购了Xamarin整合到Visual Studio里并将其开源到现在已有三年多时间,从.net core 1.0 到现在的2.2,以及即将问世的3.0,我们看到微软正在跨平台之路越走越远,从之前的偏科学生变成了现在的三号学生,希望以为以后还会越来越好

作为微软的狂热粉,从17年底就开始热衷于.net core 的学习和使用,下面谈谈我对web 框架asp core的简单理解

1:首先第一个问题.net core和Asp core有什么区别?是同一个东西吗?

  .net core是一个统一的平台,是微软准备要用来开发移动端,桌面应用,web网站等的整体平台

  asp core 是.net core着重开发网站的web 框架,这也就就好比之前.net框架与Aps .net框架的关系,可以理解为包含关系吧

2:Asp core与原来的Asp .net框架有什么区别,它对比传统Asp .net框架到底有哪些好处?

  首先我想说,Asp core其实对比原来的Asp .net,其实可以说完全是一套新的东西(并不像之前Asp .net到Asp .net MVC,Asp .net MVC只是在原有的Asp .net框架扩展和升级,其本质还是.net框架的那一套)。

但是Asp core虽说是一套新的框架,听到说是新的东西也不要紧张,个人感觉Asp core很多基础开发的用法,还是保留了原来.net开发人员的一些开发习惯,实际开发过程中个人的感觉没有给人一种陌生的感觉

  对比Asp core与Asp .net的区别:

  • 首先一条Asp core是跨平台的,何为跨平台,就是Asp core可以部署和运行在windows以外的其他服务器上面(当然必须要在所要运行的系统上安装有运行时,好比java的JRE)比如更适合做服务器系统的linux服务器,而且并不像之前的Aps .net完全依赖IIS,新的Asp core可以部署到IIS,Nginx,Apache等其他代理服务器
  • 新的Asp.net core默认使用Kestrel作为Http请求的监听器,而并不依赖原先庞大复杂的Https.sys。Kestrel不仅仅是微软下一代的跨平台Http请求监听器,同时还提供了比Https.sys更轻量级以及更快速的Http请求处理。
  • Asp.net core与原来的Web设计另一个最大的区别在于Asp.net core(及.net core),完全抛弃了原来的使用管道模式来接收以及处理HttpRequest。在Asp.net core中允许处理中间件(Middleware)来对所有的HttpRequest来进行请求,当请求被接收到时,Asp.net core会调用注册的中间件(按照注册的顺序)对HttpRequest进行处理。这样做相比与原来使用HttpApplication的管道方式而言,其优势在于完全由开发人员决定HttpRequest需要执行怎么样的处理,没有多余的其他步骤。而原来的方式既使开发人员不希望对一个HttpRequest进行任何处理,但HttpApplication仍然会按照管道的设置依次创建HttpModel -> 激活HttpHandler -> 处理Session等。相对原来的Aps .net程序,程序性能也有很大的提升

3:传统的asp .net框架请求处理流程

  3.1 IIS服务器请求处理流程

  1,当IIS服务器接收到一个 Http请求的时候,对于IIS来说,它依赖一个叫做 HTTP.SYS 的内置驱动程序来监听来自外部的 HTTP请求。

  在操作系统启动的时候,IIS首先在HTTP.SYS中注册自己的虚拟路径。实际上相当于告诉HTTP.SYS哪些URL是可以访问的,哪些是不可以访问的(举个简单的例子:为什么你访问不存在的文件会出现 404 错误呢?就是在这一步确定的)。

  如果请求的是一个可访问的URL,HTTP.SYS会将这个请求交给 IIS 工作者进程(IIS6.0中叫做 w3wp.exe,IIS5.0中叫做 aspnet_wp.exe。)。

  每个工作者进程都有一个身份标识 以及 一系列的可选性能参数(是指诸如 回收机制的设置、超时时间设置 等等)。

  2,然后请求会首传递到ISAPI(Internet Server Application Programe Interface,互联网服务器应用程序接口),ISAPI决定如何去处理这个请求,如果服务器获取所请求的静态文件(也可以是文件,比如 jimmy.jpg)的后缀名之后,接下来会在服务器端寻找可以处理这类后缀名的应用程序,如果IIS找不到可以处理此类文件的应用程序,并且这个文件也没有受到服务器端的保护(比如代码文件,配置文件.config都是受保护的, 不受保护的比如js,css),那么IIS将直接把这个文件返还给客户端。

ISAPI是什么?到底长啥样?

ISAPI 服务器扩展是可以被 HTTP 服务器加载和调用的 DLL(动态链接库)

如图:

  3,然后ISAPI 还需调用 HttpRuntime的ProcessRequest方法,开始进入请求管道周期,请求最终走完整个管道周期,ISAPI 接收返回的数据流,并重新返还给 HTTP.SYS,最后,HTTP.SYS 再将这些数据返回给客户端浏览器。

上面文字总结可能有些枯燥,下面这张图片也许会清晰许多

 流程:请求开始=>Http.Sys=>ISAPI=>CLR/HttpRuntime=>ISAPI=>Http.Sys=>请求结束

  3.2 理解管道

  前面讲到请求在IIS中的一个简单流程,但是讲到当请求进入asp.net Runtime之后的细节,只是一笔带过,没有将请求在asp.net Runtime中到底经过了哪些处理,最终又是如何返回请求结果的,下面就来简单讲解一下整个过程

  这里会是涉及到在.net框架两个比较重要的概念:Http Module和 Http Handler

  想要理解这两个概念,首先要知道当请求进入asp.net Runtime之后会经历如下图的十九个事件

对于这个事件要废话几句,这个流程虽然看着比较多,对于初学者其实不要有太大压力,其实完全没必要去每一个都研究他,只是大概过一遍,知道有这么个东西,混个眼熟就好了

Http Module 托管模块

如果我们想要在上面某一个事件中去处理我们自己框架代码,比如要在请求到达某个事件时我们要对该请求进行筛选或者在此时记录一条日志,我们应该怎么做?

这里就需要用到Http Module了,我们可以通过Http Module在Http请求管道(Pipeline)中注册期望对应用程序事件做出反应的方法

Http Module实现了IHttpModule接口,IHttpModule接口要是实现Dispose和Init方法

Dispose:它可以在进行垃圾回收之前进行一些清理工作。

Init:我们可以在init方法中注册上面十九个事件的任意一个或者多个,并在对应的回调方法中去做实际的逻辑处理

具体代码如下:

    public class TestModule : IHttpModule
    {
        void IHttpModule.Dispose()
        {
        }

        void IHttpModule.Init(HttpApplication context)
        {
            context.EndRequest += new EventHandler(context_EndRequest);
        }

        private void context_EndRequest(object sender, EventArgs e)
        {
            /*HttpApplication对象包含了请求所需要的所有上下文对象,比如HttpContext,HttpRequest,HttpResponse,HttpSession等等,所以我们可以通过这个对象
             来完成过滤请求,记录日志等等实际开发中会用到的功能
             */
            HttpApplication application = (HttpApplication)sender;

            HttpContext context = application.Context;
            context.Response.Write("<hr><h1 style='color:#f00'>来自HttpModule的处理,请求结束</h1>");
        }
    }

值得注意的是Http Module所处理的请求通常是全局的,应用级别的,不是只针对哪一个页面,什么意思,比如把上面代码作为的例子,上面代码的效果会使所有的页面都会有 “来自HttpModule的处理,请求结束”,这句话

Http Handler 处理程序

对比Http Module,HttpHandler的处理请求的权限相对较低,维度也更细,它可以只针对特定后缀的页面,其实我们的webform页面其实也就是一个Handler

所有aspx页面继承System.Web.UI.Page,可以看到Page类也实现了IHttpHandler接口

public interface IHttpHandler{
    void ProcessRequest(HttpContext context);
    bool IsReusable { get; }
}
  • ProcessRequest 用来处理请求的主要代码。
  • IsReusable 属性,MSDN上是这样解释的:获取一个值,该值指示其他请求是否可以使用 IHttpHandler 实例。也就是说后继的Http请求是不是可以继续使用实现了该接口的类的实例,一般来说,我把它设置成true。

 我们HttpHandler用的比较多的场景就是有Ajax+Httphandler进行web无刷新页面开发,然后就是HttpHandler实现图片防盗链,IhttpHandler实现图片验证码等等,传统的Http Module和HttpHandler编写程序,其实都是比较老的开发方式了,个人感觉只需要学习和了解.net有这两个东西就好了

经过上面基础的学习,我们来总计一下进入asp.net Runtime之后,和Http Module和HttpHandler发生了哪些关系,梳理出一个流程

  1. 请求进入HttpRuntime
  2. HttpRuntime 通过HttpApplicationFactory 创建 HttpApplication对象(HttpApplication代表着程序员创建的Web应用程序。HttpApplication创建针对此Http请求的 HttpContext对象,这些对象包含了关于此请求的诸多其他对象如HttpRequest、HttpResponse、HttpSessionState)
  3. 接下来Http请求通过一系列Module对请求进行应用级别的处理
  4. Http Module处理完成后会把请求转交给HttpHandler去进行一些定制化的页面级别的处理
  5. HttpHandler在处理完成后又会转回Http Module做一些后续的收尾处理

 以上就是整个Asp.Net的生命周期,虽然在这之后,出现了Asp.Net MVC,正如前面所说,但是Asp.Net MVC框架并不是一套新的框架,Asp.net Mvc还是以Asp.net运行时为基础的。但是Asp Core并不再以Asp.netRuntime为基础的,所以它也没有了十九个事件,也没有了Http Module和HttpHandler这一套,但是Asp Core引入了一些新的核心概念如中间件(middleware),控制反转容器(DI)等等,那么我会在下一篇文章简单解析Asp Core一些相关概念,以及它的的请求周期

 

参考资料:

http://go.microsoft.com/?linkid=8101007

https://docs.microsoft.com/en-us/previous-versions/aspnet/ms227435(v=vs.100)

http://www.tracefact.net/tech/001.html

https://www.cnblogs.com/me-sa/archive/2009/06/01/MVCLifecycle.html

posted @ 2019-06-27 17:49  骇客HK  阅读(908)  评论(2编辑  收藏  举报