当用户在浏览器输入一个URL地址后,浏览器会发送一个请求到服务器。这时候在服务器上第一个负责处理请求的是IIS。然后IIS再根据请求的URL扩展名将请求分发给不同的处理程序处理。

  流程如下:

  

当请求一个经由IIS进入到对应处理程序后:

从请求进入ASP.NET工作者进程,直至它到达最终的处理程序之前要经过一系列的步骤和过程,这个步骤和过程称为ASP.NET处理管道。

  Asp.net的处理管道流程如下:

  

  1. Asp.net处理管道的第一步是创建HttpWorkerRequest对象,它包含于当前请求有关的所有信息。
  2. HttpWorkerRequest把请求传递给HttpRuntime类的静态ProcessRequest方法。HttpRuntime首先要做的事是创建HttpContext对象,并用HttpWorkerRequest进行初始化。
  3. 创建了HttpContext实例之后,HttpRuntime类就通过调用HttpApplicationFactory的静态GetApplicationInstance()方法,为该应用程序请求HttpApplication派生类的一个示例。GetApplicationInstance()方法要么创建一个HttpApplication类的一个新实例,要么从应用程序对象池中取出一个实例。
  4. 在创建完成HttpApplication实例之后,就对它进行初始化,并在初始化期间分配应用程序定义的所有模块。
  5. 模块式实现IHttpModule接口的类,作用就是为了实现那经典的19个标准处理事件。
  6. 在创建了模块之后,HttpRuntime类通过调用它的BeginProcessRequest方法,要求最新检索到的HttpApplication类对当前请求提供服务。然后,为当前请求找到合适的处理程序工厂。
  7. 创建处理程序,传递当前HttpContext,一旦ProcessRequest方法返回,请求完成。

在HttpRuntime创建了HttpContext对象之后,HttpRuntime将随后创建一个用于处理请求的对象,这个对象的类型为HttpApplication。

在HttpApplication中,利用.Net中的事件机制,通过在处理过程中依次发出的多个事件,将这个处理过程分解为多个步骤,这个处理机制通常我们称为处理管道。MVC生命周一共分成19个事件。

HttpApplication的19个标准事件如下:(HttpRuntime维护着一个HttpApplication池,当有HTTP请求过来,从池中选取可用的HttpApplication处理请求,可见!HttpRuntime是入口)

HttpApplication有19个管道事件,分别是:

1、BeginRequest:HTTP管道开始处理请求时,会触发BeginRequest事件
2、AuthenticateRequest:安全模块对请求进行身份验证时触发该事件
3、PostAuthenticateRequest:安全模块对请求进行身份验证后触发该事件
4、AuthorizeRequest:安全模块对请求进程授权时触发该事件
5、PostAuthorizeRequest:安全模块对请求进程授权后触发该事件
6、ResolveRequestCache:缓存模块利用缓存直接对请求进程响应时触发该事件
7、PostResolveRequestCache:缓存模块利用缓存直接对请求进程响应后触发该事件
8、PostMapRequestHandler:对于访问不同的资源类型,ASP.NET具有不同的HttpHandler对其进程处理。对于每个请求,ASP.NET会根据扩展名选择匹配相应的HttpHandler类型,成功匹配后触发该事件
9、AcquireRequestState:状态管理模块获取基于当前请求相应的状态(比如SessionState)时触发该事件
10、PostAcquireRequestState:状态管理模块获取基于当前请求相应的状态(比如SessionState)后触发该事件
11、PreRequestHandlerExecute:在实行HttpHandler前触发该事件
12、PostRequestHandlerExecute:在实行HttpHandler后触发该事件
13、ReleaseRequestState:状态管理模块释放基于当前请求相应的状态时触发该事件
14、PostReleaseRequestState:状态管理模块释放基于当前请求相应的状态后触发该事件
15、UpdateRequestCache:缓存模块将HttpHandler处理请求得到的相应保存到输出缓存时触发该事件
16、PostUpdateRequestCache:缓存模块将HttpHandler处理请求得到的相应保存到输出缓存后触发该事件
17、LogRequest:为当前请求进程日志记录时触发该事件
18、PostLogReques:为当前请求进程日志记录后触发该事件
19、EndRequest:整个请求处理完成后触发该事件

我们可以在全局配置文件Global.asax中,按照约定的规则Application_{Event Name}来对管道事件定制:

HttpApplication提供了基于事件的扩展机制,允许程序员借助于处理管道中的事件进行处理过程扩展。由于HttpApplication对象是由Asp.net基础架构来创建和维护的,那么,如何才能获取这个对象的引用,以便于注册HttpApplication对象的事件处理,在Asp.net中,提供了两种方式来解决这个问题:IHttpModule方式和golbal.asax方式。这两种方式的核心都是IHttpModule接口。

IHttpModule接口的定义如下,其中仅仅包含两个成员:

public interface IHttpModule
{
void Dispose();
void Init(HttpApplication app)
}

  其中,Dispose方法用于回收Module所使用的非托管资源,如果没有的话,直接返回即可。

  最重要的是Init方法,可以看到,这个方法接收一个HttpApplication类型的参数,在Asp.net中,每当创建一个HttpApplication对象实例,将遍历注册的HttpModule类型,通过反射,依次每个注册HttpModule类型的一个实例对象,并将这个HttpApplication实例通过Init方法传递给各个HttpModule,这样HttpModule就可以在第一时间完成针对HttpApplication对象的事件注册了。

  例如:自定义一个Module


public class TestModule : IHttpModule
{
public void Dispose(){}
public void Init(HttpApplication app)
{
app.PostAcquireRequestState += new EventHandler(app_PostAcuiredRequestState);
app.PreRequestHandlerExecute += new EventHandler(app_PreRequestHandlerExecute);
} void app_PreRequestHandlerExecute(object sender, EventArgs e)
{
//TODO:
} void app_PostAcquiredRequestState(object sender, EventArgs e)
{
//TODO:
}
}

当某个请求与一个规则匹配后,ASP.NET会调用匹配的HttpHandlerFactory的GetHandler方法来获取一个HttpHandler实例, 最后由一个HttpHandler实例来处理当前请求,生成响应内容

所有的HttpHandlers都实现了IHttpHandler接口:

public interface IHttpHandler
{
bool IsReusable{get;}
void ProcessRequest(HttpContext context);
}

比如我们可以自定义一个HttpHandler来响应一类特定的请求:

public class Login : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string username = context.Request.Form["name"];
string password = context.Request.Form["password"]; if(password="sth")
{
System.Web.Security.FormsAuthentication.SetAuthCookie(username, false);
context.Response.Write("ok");
}
else
{
context.Response.Write("用户名和密码不正确");
}
}
}

global.asax中HttpApplication事件的自动注册

  在global.asax中,针对HttpApplication的事件处理,可以通过定义特殊命名的方法来实现。首先,这些方法必须符合System.EventHandler,因为所有的HttpApplication管道事件都使用这个委托定义。第二,方法的作用域必须是public。第三,方法的命名格式必须如下:Application_注册的事件名称。按照这种命名方法定义在global.asax中的方法将被自动注册到对应的事件中。

  例如,希望在global.asax中注册PostAuthenticateRequest事件处理,那么在global.asax中应该定义一个如下的方法:

    void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
Response.Write("验证通过事件!");
}

原文转载自:https://www.cnblogs.com/changrulin/category/725993.html 和 https://www.cnblogs.com/changrulin/p/4769353.html 和 https://www.cnblogs.com/kissdodog/p/3527379.html 和 https://www.cnblogs.com/kissdodog/p/3527922.html

MVC Request生命周期(综合总结)的更多相关文章

  1. SpringMVC request生命周期

    When the request leaves the browser, it carries information about what the user is asking for. At ve ...

  2. node.js WebService异常处理(domain)以及利用domain实现request生命周期的全局变量

    成熟的Web Service技术,例如Fast CGI.J2EE.php,必然会对代码异常有足够的保护,好的Web必然会在出错后给出友好的提示,而不是莫名其妙的等待504超时.而node.js这里比较 ...

  3. Erlang cowboy http request生命周期

    Erlang cowboy http request生命周期 翻译自: http://ninenines.eu/docs/en/cowboy/1.0/guide/http_req_life/ requ ...

  4. C# MVC 5 - 生命周期(应用程序生命周期&请求生命周期)

    本文是根据网上的文章总结的. 1.介绍 本文讨论ASP.Net MVC框架MVC的请求生命周期. MVC有两个生命周期,一为应用程序生命周期,二为请求生命周期. 2.应用程序生命周期 应用程序生命周期 ...

  5. javaBean Request生命周期

    request: 在request范围内,JavaBean对象的有效范围为: ① 客户请求访问的当前JSP页面② 和当前JSP页面共享同一个请求的页面,包括<%@ include%>指令以 ...

  6. .NET MVC页面生命周期及传统ASP.NET页面周期

    目前我主要使用.Net MVC框架进行网页创建,数据库是MSSQL Server.所以,我就用.NET MVC框架的web页面周期来说明页面的生命周期,但是我觉着其他MVC框架也是大同小异的. 本文主 ...

  7. 【MVC】ASP.NET MVC 请求生命周期

    当一个asp.net mvc应用程序提出请求,为了响应请求,包含一些请求执行流程步骤! 在asp.net mvc应用程序Http request和Http response 过程中,主要包含8个步骤: ...

  8. mvc的生命周期

    尽管每次都是从msdn里复制粘贴,但是还是有必要的,加深对mvc的理解和官方的表述. 了解 MVC 应用程序执行过程 发送给基于 ASP.NET MVC 的 Web 应用程序的请求首先通过 UrlRo ...

  9. MVC网址路由与生命周期

    这篇写得比较详细,所以我收藏一下. 转载自: http://www.cnblogs.com/Eleanore/archive/2012/11/23/2783061.html 一.网址路由 1.1  比 ...

随机推荐

  1. springboot项目简单启动脚本

    #!/bin/bash function log_info () { DATE=`date "+%Y-%m-%d %H:%M:%S"` USER=$(whoami) echo &q ...

  2. php中一个"异类"语法: $a && $b = $c; 【转载】

    $a = 1;$b = 2;$c = 3;$a && $b = $c;echo "a:$a";echo "b:$b";echo "c: ...

  3. java-其他-索引

    数据结构 设计模式 算法题

  4. Btrace官方教程-中文版

    教程英文版来源:https://github.com/btraceio/btrace/blob/master/docs/usersguide.html BTrace用户指南 BTrace是一种安全,动 ...

  5. Spring boot 自定义拦截器

    1.新建一个类实现HandlerInterceptor接口,重写接口的方法 package com.zpark.interceptor; import com.zpark.tools.Constant ...

  6. chrome 如何开启网页另存为.mhtml 功能

    打开chrome浏览器,输入地址:chrome://flags/   找到将网页另存为MHTML,点击启用就可以了. 或者直接输入:chrome://flags/#save-page-as-mhtml

  7. selenium2 webdriver 常用的python 函数

    新建实例driver = webdriver.Chrome() 1.通过标签属性Id查找元素 方法:find_element_by_id(element_id) 实例:driver.find_elem ...

  8. ==和equals的比较方式

    关系操作符生成的是一个boolean结果,它们计算的是操作数的值之间的关系.——摘自<Java编程思想> 多读几遍之后你会发现——这不就是句废话么233333.(开个玩笑不要打我) 先说 ...

  9. Python——Django运行问题

    1.Python3.7+Django2.2操作Mysql数据库时出现如下错误:django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3. ...

  10. mysql 线程操作

    show processlist;//查询mysql所有连接线程 SELECT CONCAT('KILL ',id,';') FROM information_schema.`PROCESSLIST` ...