Asp.net本质论之应用程序对象

来源:互联网 发布:软件模块接口 规范 编辑:程序博客网 时间:2024/05/17 13:39
主题 概要 Asp.net 应用程序对象 编辑 时间 新建 20171018 序号 参考资料 1 Asp.net本质论 2 https://msdn.microsoft.com/en-us/library/system.web.httpapplication(v=vs.110).aspx 3 https://msdn.microsoft.com/en-us/library/system.web.ihttpmodule(v=vs.110).aspx

在上一篇ASP.net本质论之用控制台应用程序创建Asp.net服务器
中基本理清了服务器监听部分及怎么创建自己的应用程序域和处理程序。本篇对当请求到达后,asp.net如何处理的内容做一个学习总结。

针对每一次请求,ASP.net将创建一个处理这次请求所使用的HttpContext对象实例,这个对象实例将用来在ASP.net服务器的处理过程中传递所有需要的参数,在请求到达Asp.net服务器之后,这个对象将被创建出来,在一次请求处理之后,这个对象将被丢弃掉。HttpContext对象包括了HttpRequest类型的对象以表示请求参数,HttpResponse类型的对象以表示回应的处理对象,另外还有HttpServerUtility类型的对象等。

当HttpContext对象被创建之后,HttpRuntime将随后创建一个用于处理请求的对象,这个对象的类型为HttpApplication。
在ASP.net内部,HttpRuntime管理一个定义在System.Web命名空间下的HttpApplicationFactory类的实例,HttpApplicationFactory通过工厂模式管理HttpApplication对象,在HttpApplicationFactory内部维护了一个HttpApplication对象池,使得被创建的HttpApplication对象可以被重复使用。

处理管道

所谓的处理管道,就是处理复杂问题的时候,将处理的过程分解为多个处理步骤,我们将这种经过多个步骤的处理方式称为处理管道。如下图所示:
这里写图片描述

这些管道步骤实际上是一系列的事件,MSDN
https://msdn.microsoft.com/en-us/library/system.web.httpapplication(v=vs.110).aspx
中详解了这些事件。程序员通过编写事件处理方法就可以自定义每一个请求的扩展处理过程。

那HttpApplication是怎么样定义这么多事件的呢?

通过继承System.ComponentModel.Component类,对于这个派生类所需要定义的每一个事件,在类中定义一个对应的作为key的对象,以后,通过这个key对象来访问由Events集合管理的事件。

下面的代码演示了一个Mini的处理管道,没有HttpApplication这么多事件,但定义过程类似:

定义:

namespace Aspnet.Pipe{    public class ProcessPipeline:System.ComponentModel.Component    {        private static readonly object startEvent = new object();        private static readonly object preProcessEvent = new object();        private static readonly object postProcessEvent = new object();        private static readonly object endEvent = new object();        public event EventHandler StartEvent        {            add { this.Events.AddHandler(startEvent, value); }            remove { this.Events.RemoveHandler(startEvent, value); }        }        public event EventHandler PreProcessEvent        {            add { this.Events.AddHandler(preProcessEvent, value); }            remove { this.Events.RemoveHandler(preProcessEvent, value); }        }        public event EventHandler PostProcessEvent        {            add { this.Events.AddHandler(postProcessEvent, value); }            remove { this.Events.RemoveHandler(postProcessEvent, value); }        }        public event EventHandler EndEvent        {            add { this.Events.AddHandler(endEvent, value); }            remove { this.Events.RemoveHandler(endEvent, value); }        }        protected void OnStartProcess(EventArgs e)        {            if(this.Events[startEvent]!=null)            {                (this.Events[startEvent] as EventHandler)(this,e);            }        }        protected void OnPreProcess(EventArgs e)        {            if (this.Events[preProcessEvent] != null)            {                (this.Events[preProcessEvent] as EventHandler)(this, e);            }        }        protected void OnPostProcess(EventArgs e)        {            if (this.Events[postProcessEvent] != null)            {                (this.Events[postProcessEvent] as EventHandler)(this, e);            }        }        protected void OnEndEvent(EventArgs e)        {            if (this.Events[endEvent] != null)            {                (this.Events[endEvent] as EventHandler)(this, e);            }        }        public void Process()        {            Console.WriteLine("开始处理....");            this.OnStartProcess(EventArgs.Empty);            Console.WriteLine("准备处理....");            this.OnPreProcess(EventArgs.Empty);            Console.WriteLine("正在处理....");            this.OnPostProcess(EventArgs.Empty);            Console.WriteLine("处理完成....");            this.OnEndEvent(EventArgs.Empty);        }    }}

使用:

public static void Main()        {            ProcessPipeline process = new ProcessPipeline();            process.StartEvent += new EventHandler(startProcessHandler);            process.PreProcessEvent += new EventHandler(preProcessHandler);            process.PostProcessEvent += new EventHandler(postProcessHandler);            process.EndEvent += new EventHandler(endProcessHandler);            process.Process();        }        public static void startProcessHandler(object sender,EventArgs e)        {            Console.WriteLine("开始处理的事件处理。。。。。");        }        public static void preProcessHandler(object sender, EventArgs e)        {            Console.WriteLine("预处理的事件处理。。。。。");        }        public static void postProcessHandler(object sender, EventArgs e)        {            Console.WriteLine("处理后的事件处理。。。。。");        }        public static void endProcessHandler(object sender, EventArgs e)        {            Console.WriteLine("处理完成的事件处理。。。。。");        }

结果:

这里写图片描述

处理HttpApplication的事件

程序员对HttpApplication的事件进行处理过程扩展,关键点是如何引用这个HttpApplication对象,因为HttpApplication对象是由Asp.net基础架构来创建和维护的。
在ASP.net中提供了两种方式:IHttpModule方式和global.asax方式。

通过IHttpModule创建HttpApplication事件处理程序

第一步:实现IHttpModule接口,接口说明参照MSDN:
https://msdn.microsoft.com/en-us/library/system.web.ihttpmodule(v=vs.110).aspx

并参加MSDN上的例子:
https://msdn.microsoft.com/en-us/library/ms227673(v=vs.110).aspx

第二步:注册HttpModule
在Asp.net中,实现IHttpModule接口只是实现HttpModule的第一步,在Asp.net中所使用的HttpModule还必须在网站配置文件中进行注册才能真正生效,并在Asp.net中使用。

在网站的配置文件web.config中,system.web配置元素的子元素httpModules用来配置网站所使用的HttpModule;httpModules的子元素用来增加一个新的HttpModule,clear将清除前面注册的所有HttpModule。

Add元素有两个必选的属性name和type,简介如下:

Name:表示这个HttpModule在程序中的名字,作为索引器的唯一标识。
Type:表示HttpModule对象的类型名,asp.net网站可以使用这个类型名,通过反射来动态创建HttpModule对象。如果不在同一个命名空间,要加上程序集名称,并用逗号分隔。

通过global.asax创建HttpApplication事件处理

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