zoukankan      html  css  js  c++  java
  • ASP.NET WebForm / MVC 源码分析

    浏览器 Url:https//localhost:6565/Home/Index ,https//localhost:6565/WebForm1.aspx,请求服务器(构建请求报文,并且将请求报文发送给服务器)

    1:服务器(内核模式 Http.sys)对请求报文做基本的处理

    2:请求服务器(用户模式,IIS服务器)

      2.1:对发送过来的数据做一个检查,如果请求的是静态资源的(.html,jpg,js),那么IIS直接将这些资源返回浏览器

      2.2:如果是动态资源(.aspx,.ashx),IIS服务器无法直接处理,请求W3wp.exe进程(非托管模式/托管模式)

      2.3:非托管模式(aspnet_isapi.dll),加载运行时,然后将数据传递.NetFrameWork,然后进入托管模式

      (以上步骤无法通过代码验证,微软没有开源,以下步骤可以通过Reflector查看源代码)

      2.4:托管模式(ISAPIRuntime),非常重要的方法

      public int ProcessRequest(IntPtr ecb, int iWRType)  //ecb 句柄:是操作系统的概念,指的就是资源的编号,操作系统将所有的资源都加上相应的编号。

    Reflector 7百度云盘:链接:http://pan.baidu.com/s/1eSm9Y06  密码:gyx0

    1:用Reflector 搜索ISAPIRuntime

    2:查看里面的ProcessRequest方法,根据ecb句柄创建出ISAPIWorkerRequest(封装的是请求报文最原始的数据)

    3:HttpRuntime.ProcessRequstNoDemand(wr); //将HttpWorkerRequest传递到HttpRuntime中

    4:ProcessRequestNow方法

    5:ProcessRequestInternal方法

           在HttpRuntime中创建了HttpContext(context=new HttpContext(wr,false)); //最终请求报文的数据封装到了HttpContext(HttpRequest/HttpResponse)

    5.1:在HttpContext类中初始化:new HttpRequest(wr,this);//接收数据 

                      new HttpResponse(wr,this);//输出数据

         

    5.2:ProcessRequestInternal中GetApplicationInstance方法 (HttpContext类初始化之后)

    创建了一个HttpApplication对象,负责处理浏览器发送过来的数据,由于请求报文的数据都封装到了HttpContext中,

    那么在这里需要将HttpContext传递到HttpApplication中,HttpApplication是怎么被创建的呢?

    IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context); //是通过HttpApplicationFactory工厂创建出的HttpApplication.

    在创建HttpApplication的时候,用到了HttpApplication池的应用,在创建时先看一下池中有没有空闲的HttpApplication,如果有直接拿出来用,用完以后再放入池中。

    在这里这个池就是栈(stack),如果池中没有空闲的,那么就创建一个。

    1:HttpApplication对象一次只能处理一个请求。这里的HttpApplication对象的生命周期只针对与动态内容的请求,静态内容IIS直接帮我们处理了

    2:而对于HttpApplication中的其它19个事件,则对于每个请求(请求动态内容)都会触发一次

    3:Application_Start是在用户第一次请求动态内容的时候触发一次(在真正的IIS中)

         Application_End在整个应用程序结束的时候,比如:重启IIS/重启网站/重启对应网站的"应用程序池",结束w3wp.exe进程的情况下

    6:查看 IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);

    6.1  theApplicationFactory.EnsureInited();

    6.2 theApplicationFactory.EnsureAppStartCalled(context);

    _theApplicationFactory.EnsureAppStartCalled(context);确保Global文件中的Application_Start方法被调用,而且只调用一次。

    6.3 return _theApplicationFactory.GetNormalApplicationInstance(context);

    state=(HttpApplication)HttpRuntime.CreateNonPublicInstance(this._theApplicationType);

    (通过反射的形式将Global文件编译的类型创建出HttpApplication)//创建HttpApplication对象

    //找到Global.asax文件并且对Global.asax文件进行编译,编译出_theApplicationType,调用[_theApplicationFactory.EnsureInited();]

    7: state.InitInternal(context, this._state, this._eventHandlerMethods);

    8: this.InitModules();

    当创建出HttpApplication以后,会遍历Web.config文件中关于HttpModule的信息,然后执行其中的Init方法。

     1 private void InitModulesCommon()
     2 {
     3     int count = this._moduleCollection.Count;
     4     for (int i = 0; i < count; i++)
     5     {
     6         this._currentModuleCollectionKey = this._moduleCollection.GetKey(i);
     7         this._moduleCollection[i].Init(this);
     8         //在这里有一个非常重要的Module就是UrlRouteingModule
     9         //在UrlRouteingModule中的Init方法中定义了:
    10         //application.PostResolveRequestCache+=new EventHandler(this.OnApplicationPostResolveRequestCache);
    11     }
    12     this._currentModuleCollectionKey = null;
    13     this.InitAppLevelCulture();
    14 }
    15 
    16 /*
    17 Ps:1:新建一个类,实现IHttpModule接口,
    18        实现public void Dispose(){};和 public void Init(HttpApplication context){};
    19    2:web.config中配置HttpModule节点
    20 */
    InitModulesCommon

    接下里就要进入管道事件模型 (Application  19事件)

    从HttpApplication对象创建开始,调用ProcessRequest方法,到调用结束,整个过程叫做"ASP.NET应用的生命周期"(不是ASP.NET页面的生命周期)

    【处理用户请求:会触发19个事件,23步骤】

    ASP.NET 应用生命周期19个事件简介  http://www.cnblogs.com/Dr-Hao/p/5380019.html

    9:到达第7个事件(MVC和WebForm的区别),会通过EventHandler委托调用OnApplicationPostResolveRequestCache执行该方法中的代码。

    9.1:ASP.NET WebForm

    在asp.net应用程序的生命周期的第7个事件和第8个事件之间,创建了用户请求的ashx或者aspx页面的对象。

    如果是aspx页面的话,在这里创建的页面的对象不是aspx对应的后台类的对象,而是aspx页面编译后生成的类的对象,该类型继承自后台代码文件。

    所以创建了该类型的对象就拥有了后台代码文件中的所有东西。

    【未完 待续】

    9.2:ASP.NET MVC

    在这里有一个非常重要的Module就是UrlRouteingModule (UrlRouteingModule中的Init方法)

    在UrlRouteingModule中的Init方法中定义了:

    application.PostResolveRequestCache+=new EventHandler(this.OnApplicationPostResolveRequestCache);

    1:[第7~8事件之间]到达第7个事件,会通过EventHandler委托调用OnApplicationPostResolveRequestCache执行该方法中的代码

    2:[第11~12事件之间] 开始执行MvcHandler中的ProcessRequest方法

    ASP.NET MVC源码分析:http://www.cnblogs.com/DrHao/p/5315556.html

  • 相关阅读:
    dropload.js 上滑加载,下拉刷新
    jQuery支持图片放大缩小查看效果
    iScroll-5 API 中文版
    多行文字垂直居中
    jQuery延迟加载(懒加载)插件 – jquery.lazyload.js
    js生成中文二维码
    JS中,如何判断一个数是不是小数?如果是小数,如何判断它是几位小数??
    HTML5页面,用JS 禁止弹出手机键盘
    watch和computed的用法区别是什么?
    JS中的call()和apply()
  • 原文地址:https://www.cnblogs.com/DrHao/p/5315448.html
Copyright © 2011-2022 走看看