zoukankan      html  css  js  c++  java
  • 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:WindowsMicrosoft.NETFrameworkv4.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:WindowsMicrosoft.NETFrameworkv2.0.50727CONFIG     这个配置给出了一些模板、

     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格式。RSS类型。

    先看效果图

      ①新建一个类

    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接口,然后完成一些操作,等学会了到时候在记录一下。

  • 相关阅读:
    RTB交接
    awk命令详解
    Linux下的压缩解压缩命令详解
    inux下文件权限设置中的数字表示权限,比如777,677等,这个根据什么得来的
    jmeter接口测试教程
    kafka常用的操作命令
    hadoop常用的操作命令
    linux常用命令
    hive的常用命令
    用shell脚本写一个for循环
  • 原文地址:https://www.cnblogs.com/Sea1ee/p/7479576.html
Copyright © 2011-2022 走看看