HttpHandler(处理程序) 和 HttpModule(托管模块)

本文参见:http://www.tracefact.net/Asp-Net/Introduction-to-Http-Handler.aspx

前言:前几天看到一个DTcms网站,里面有个伪静态技术,那我之前也写过一个伪静态,是通过一个URlWrite类在配置文件里面配置就可以了。而他的网站结构不同于我先前介绍的,网站里面是把页面与代码完全分离,页面是纯粹的HTML页面,代码就是*.cs文件,利用他里面介绍的语法可以在HTML页面写后台代码。这个是非常值得学习的。这篇文章就是打的基础。之前在配置的伪静态在config文件里面也出现了这两个配置,当时并没有去了解原理,这次碰到了才来深入了解。

Http请求

当服务器接收到一个 Http请求的时候,IIS 首先需要决定如何去处理这个请求(NOTE:服务器处理一个.htm页面和一个.aspx页面肯定是不一样的么)。那IIS依据什么去处理呢?―― 根据文件的后缀名。

如何配置:

打开我们需要配置的网站(演示的IIS是本地的)

找到 处理程序映射

我们可以添加我们自己需要的,列如:我需要在网站中打开 *.test 后缀名的

①右键 添加脚本映射

C:\Windows\Microsoft.NET\Framework\v4.0.30319   此文件夹是存放 dll文件的。下面的这个dll是主要的。

IIS里面添加了以后,在配置文件里面写才会有反应。后面会说。

HTTP管道:

需要注意的:

4.0以下:

  <system.web>
    <httpHandlers>
      <add path="*.jpg" verb="*" name="DTcmsTest" type="DTcmsTest.IHttpHandlerDemo.CustomHandler" />
      <add path="*.rss" verb="*" name="RssTest" type="DTcmsTest.Rss.RSSHandler"/>
    </httpHandlers>
    <httpModules>
      <add name="MyModule" type="DTcmsTest.IHttpModuleDemo.ModuleDemo"/>
    </httpModules>

  </system.web>

而4.0或以上

<system.webServer>
    <handlers>
      <add path="*.jpg" verb="*" name="DTcmsTest" type="DTcmsTest.IHttpHandlerDemo.CustomHandler" />
      <add path="*.rss" verb="*" name="RssTest" type="DTcmsTest.Rss.RSSHandler"/>
    </handlers>
    <modules>
      <add name="MyModule" type="DTcmsTest.IHttpModuleDemo.ModuleDemo"/>
    </modules>
  </system.webServer>

C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG     这个配置给出了一些模板、

HttpHandler

IHttpHandler接口

    //
    // 摘要:
    //     定义 ASP.NET 为使用自定义 HTTP 处理程序同步处理 HTTP Web 请求而实现的协定。
    public interface IHttpHandler
    {
        //
        // 摘要:
        //     获取一个值,该值指示其他请求是否可以使用 System.Web.IHttpHandler 实例。
        //
        // 返回结果:
        //     如果 System.Web.IHttpHandler 实例可再次使用,则为 true;否则为 false。
        bool IsReusable { get; }

        //
        // 摘要:
        //     通过实现 System.Web.IHttpHandler 接口的自定义 HttpHandler 启用 HTTP Web 请求的处理。
        //
        // 参数:
        //   context:
        //     System.Web.HttpContext 对象,它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session
        //     和 Server)的引用。
        void ProcessRequest(HttpContext context);

模板如下:

public class CustomHandler : IHttpHandler{
    public void ProcessRequest(HttpContext context)  {
       // 处理请求的代码
    }
    public bool IsReusable {
       get { return true; }
    }
}

一般处理程序我们用的很多。我们配置这个,在URL上访问 *.jpg来显示一张图片。

①写好代码,需要继承IHttpHandler接口的

namespace DTcmsTest.IHttpHandlerDemo
{
    /// <summary>
    /// 继承这个接口  并实现
    /// </summary>
    public class CustomHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            string FileName = context.Server.MapPath(context.Request.FilePath);
            context.Response.ContentType = "image/JPEG";
            context.Response.WriteFile("/Img/2.jpg"); //我们输出一张图片
        }
        public bool IsReusable
        {
            get
            {
                return true;
            }
        }
    }
}

②注册 config文件

  <system.webServer>  此节点下
    <handlers>
      <!--  path指的是请求的文件名称,可以使用通配符扩大范围
            verb指的是请求的方式,get或post,*代表所有访问方式
            name就是名称,可以随便写
            type属性有 “,”分隔成两部分
            第一部分是现实了接口的类名  全称,带命名空间
            第二部分是位于bin目录下的编译过的程序集名称,有则写,无可不写            这里配置了*.jpg,按理说IIS上也要配置相同的名字,IIS有一些帮你声明了,如果不行就去IIS上补一下
      -->
     <add path="*.jpg" verb="*" name="DTcmsTest" type="DTcmsTest.IHttpHandlerDemo.CustomHandler" />
    </handlers>
       </system.webServer>  

③url上随便输入*.jpg就可以看到图片,代码里面不写错,随便哪个目录都可以看到此图片(其实就是访问*.jpg就可以去访问CustomHandler类了)

这个输出验证码很常用的,这里就不介绍了。 在来看第二个列子,输出XML格式。

先看效果图

①新建一个类

namespace DTcmsTest.Rss
{
    /// <summary>
    /// 字符串格式
    /// </summary>
    public class RssFeedsLib
    {
        public static string GetRSS()
        {
            MemoryStream ms = new MemoryStream();
            XmlWriter writer = new XmlTextWriter(ms, null);
            SqlConnection conn = new SqlConnection("server=.;uid=sa;pwd=a123;database=Sample;");
            SqlCommand cmd = new SqlCommand("select * from RssSample order by pubdate desc", conn);
            conn.Open();
            SqlDataReader reader = cmd.ExecuteReader();

            writer.WriteStartElement("rss"); //新建一个元素
            writer.WriteAttributeString("version", "2.0"); //设置属性
            writer.WriteStartElement("channel");
            // Channel 下的结点静态写入
            writer.WriteElementString("title", "TraceFact.Net 技术文章");
            writer.WriteElementString("link", "http://www.tracefact.net");
            writer.WriteElementString("description", "Dedicated to asp.net...");
            writer.WriteElementString("copyright", "Copyright (C) 2007");
            writer.WriteElementString("generator", "My RSS Generator");

            // Item 结点从数据库读取
            while (reader.Read())
            {
                writer.WriteStartElement("item");
                writer.WriteElementString("author", reader.GetString(reader.GetOrdinal("Author")));
                writer.WriteElementString("title", reader.GetString(reader.GetOrdinal("title")));
                writer.WriteElementString("link", reader.GetString(reader.GetOrdinal("Link")));
                writer.WriteElementString("description", reader.GetString(reader.GetOrdinal("Description")));
                writer.WriteElementString("pubDate", reader.GetDateTime(reader.GetOrdinal("PubDate")).ToString(@"ddd, dd MMM yyyy 12:00:00 tt "));
                writer.WriteEndElement();
            }

            writer.WriteEndElement();
            writer.WriteEndElement();
            reader.Close();
            conn.Close();

            writer.BaseStream.Flush();
            writer.Flush();
            ms.Flush();
            // 将流转换成String并返回
            byte[] data = new byte[ms.Length];
            ms.Seek(0, SeekOrigin.Begin);
            ms.Read(data, 0, data.Length);
            ms.Close();
            return UTF8Encoding.UTF8.GetString(data);

        }
    }

}

② 新建一个一般处理程序或类,在里面去调用方法

namespace DTcmsTest.Rss
{
    /// <summary>
    /// RSSHandler 的摘要说明  XML格式
    /// </summary>
    public class RSSHandler : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            context.Response.ContentEncoding = System.Text.Encoding.UTF8;
            context.Response.ContentType = "text/xml";  //需要设置这个格式

            string aa = RssFeedsLib.GetRSS();
            context.Response.Write(aa);

如果是一般处理程序,我们访问这个是没有问题的,是类就访问不了。

③注册 config文件

URL随便输入 *.rss就可以得到信息

HttpModul

定义:Asp.Net中的事件分成三个级别,最顶层是 应用程序级事件、其次是页面级事件、最下面是控件级事件,事件的触发分别与 应用程序周期、页面周期、控件周期紧密相关。而 Http Module 的作用是与应用程序事件 密切相关的。 

namespace System.Web
{
    //
    // 摘要:
    //     向实现类提供模块初始化和处置事件。
    public interface IHttpModule
    {
        //
        // 摘要:
        //     处置由实现 System.Web.IHttpModule 的模块使用的资源(内存除外)。
        void Dispose();
        //
        // 摘要:
        //     初始化模块,并使其为处理请求做好准备。
        //
        // 参数:
        //   context:
        //     一个 System.Web.HttpApplication,它提供对 ASP.NET 应用程序内所有应用程序对象的公用的方法、属性和事件的访问
        void Init(HttpApplication context);
    }
}

实现一个IHttpModult模板如下:

public class ModuleDemo:IHttpModule
{
    public void Init(HttpApplication context) {
       // 注册HttpApplication应用程序 BeginRequest 事件
       // 也可以是其他任何HttpApplication暴露出的事件
       context.BeginRequest += new EventHandler(context_BeginRequest);
    }

    void context_BeginRequest(object sender, EventArgs e) {
       HttpApplication application = (HttpApplication)sender;
       HttpContext context = application.Context;
       // 做些实际的工作,HttpContext对象都获得了,剩下的基本可以自由发挥了
    }

    public void Dispose() {
    }
}

①新建一个类,继承 IHttpModule接口

namespace DTcmsTest.IHttpModuleDemo
{
    public class ModuleDemo : IHttpModule
    {
        //申明一个事件
        public event EventHandler ExposedEvent;
        void IHttpModule.Init(HttpApplication context)
        {            //打开一个页面会先执行这个方法,对于每个页面都一样
            context.BeginRequest += new EventHandler(context_BeginRequest);  //调用事件
            context.EndRequest += new EventHandler(context_EndRequest);
        }

        void context_BeginRequest(object sender,EventArgs e)
        {
            HttpApplication application = (HttpApplication)sender;
            HttpContext context = application.Context;
            context.Response.Write("<h1 style=‘color:#00f‘>来自HttpModule 的处理,请求到达</h1><hr>");

        }

        void context_EndRequest(object sender,EventArgs e)
        {
            HttpContext context = ((HttpApplication)sender).Context;
            context.Response.Write("<hr><h1 style=‘color:#f00‘>来自HttpModule的处理,请求结束</h1>");
        }
    }
}

②注册 config文件

<system.webServer>  <modules>
        <!--名字随便取
         type跟上面的一样-->
      <add name="MyModule" type="DTcmsTest.IHttpModuleDemo.ModuleDemo"/>
    </modules> </system.webServer>

打开一个页面:

由这个页面可以看出,我们在执行页面之前先去执行了 IHttpModule里面的方法。

这个两个配置基本也就了解了。DTcms里面就有个 HttpModule 类继承了IHttpModule接口,然后完成一些操作,等学会了到时候在记录一下。

时间: 2024-10-10 00:22:08

HttpHandler(处理程序) 和 HttpModule(托管模块)的相关文章

HttpApplication处理对象与HttpModule处理模块 (第三篇)

一.HttpApplication对象简述 在HttpRuntime创建了HttpContext对象之后,HttpRuntime将随后创建一个用于处理请求的对象,这个对象的类型为HttpApplication. HttpRuntime管理一个定义在System.Web命名空间下的HttpApplicationFactory类的时候,HttpApplicationFactory通过工厂模式管理HttpApplication对象.在HttpApplicationFactory内部维护了一个HttpA

处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”

开发web项目时需要安装IIS,在安装好IIS的Windows7本上发布asp.net网站时,web程序已经映射到了本地IIS上,但运行如下错误提示"处理程序"PageHandlerFactory-Integrated"在其模块列表中有一个错误模块"ManagedPipelineHandler"" 我要发布的的web项目开发工具及所用系统 ①开发工具:vs2010.数据库:sqlserver ②操作系统:windows7 ③IIS:IIS 7.5

程序集与托管模块的概念(转)

程序集与托管模块的概念(转) 本文是为了学习程序集而整理的网上资料,主要包括两个部分,概念和使用,前部分讲怎样理解程序集,后部分讲述怎样使用的细节. 程序集与托管模块的概念 "程序集与托管代码块"(摘自Himage的blog),希望大家看了此篇文章后对程序集的概念清楚一点 如果你正在开发面向DotNet平台的应用程序,那么你肯定对“程序集”和“托管模块”这两个概念不陌生,这是DotNet带来的术语.这两个概念很容易混淆,有人认为它们指的是同一样事物,其实不然.这里,我写下自己的一些理解

HTTP 错误 500.21 - Internal Server Error 处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”

HTTP 错误 500.21 - Internal Server Error 处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler” 原因:在安装Framework v4.0之后,再启用IIS,导致Framework没有完全安装 解决:1.先找到 aspnet_regiis.exe文件,先看看这个文件在什么位置, 2.开始->所有程序->附件->右键点击“命令提示符”->以管理员身份运行-&

asp.net发布到IIS中出现错误:处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”

开发web项目时需要安装IIS,在安装好IIS的Windows7本上发布asp.net网站时,web程序已经映射到了本地IIS上,但运行如下错误提示“处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”” 一,上述错误详情为 二.上述错误分析:  vs2010默认采用的是.NET 4.0框架,4.0框架是独立的CLR,和.NET 2.0的不同,如果想运行.NET 4.0框架的网站,需要用aspnet_r

win7 IIS7 发布网站 出现 "处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误"

http://blog.sina.com.cn/s/blog_7ed5a8080100rinj.html win7 IIS7 发布网站 出现 "处理程序"PageHandlerFactory-Integrated"在其模块列表中有一个错误",布布扣,bubuko.com win7 IIS7 发布网站 出现 "处理程序"PageHandlerFactory-Integrated"在其模块列表中有一个错误"

HTTP 500.21 处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”

问题:处理程序"PageHandlerFactory-Integrated"在其模块列表中有一个错误模块"ManagedPipelineHandler" IIS7下部署网站出现错误,原因是先安装的IIS才安装 .NET 4.0 导致的,只要在服务器上打开以下路径,进行安装即可! %windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i

把WCF服务部署服务器IIS异常(详细:处理程序“svc-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”)

详细:处理程序“svc-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler” 原因: vs2010默认的是4.0框架,4.0的框架是独立的CLR,和2.0的不同,如果想运行4.0的网站,需要用aspnet_regiis注册4.0框架,然后用4.0的Class池,就可以运行4.0的web项目了. 如何用aspnet_regiis注册4.0框架 : 方法如下,启动cmd (win键+R 启动cmd)  ,找到 4.0所在的目录,本人机器目录是 : 注意:

【CLR via C#】CSC将源代码编译成托管模块

下图展示了编译源代码文件的过程.如图所示,可用支持 CLR 的任何一种语言创建源代码文件.然后,用一个对应的编译器检查语法和分析源代码.无论选用哪一个编译器,结果都是一个托管模块(managedmodule).托管模块是一个标准的 32 位 Microsoft Windows 可移植执行体(PE32)文件 6 ,或者是一个标准的 64 位Windows 可移植执行体(PE32+)文件,它们都需要 CLR 才能执行.顺便说一句,托管的程序集总是利用了 Windows 的数据执行保护(Data Ex