Inside.Net

自由与繁荣的国度

博客园 首页 新随笔 联系 订阅 管理
  12 Posts :: 0 Stories :: 29 Comments :: 0 Trackbacks

公告

实现IHttpHandlerFactory接口
对于在何处响应对指定资源的请求Http Handler也许是有用的,Http处理工厂使得有可能在请求的一些预处理任务中截取请求信息,下面的一个工厂模式创建了一个资源处理器。
创建一个自定义处理工厂意味着创建了一个实现了IHttpHandlerFactory接口的.Net组件,这个接口具有以下成员:
GetHandler()            这个方法为运行时处理对资源的请求操作创建了一个IHttpHandler的接口类型;
ReleaseHandler()     这个方法提供了一个机会使得可以释放一个接口类型并为下次重用处理器对象作准备。
GetHandler()方法通过运行时调用,并且只有2种返回值;Null和正确的IHttpHander接口类型。这有一个Http处理器工厂的例子展示了对于特定IP的客户端的计数统计,如果计数器超出限制那么返回一个自定义的处理器(Handler),反之对这些资源的请求传递控件到默认的处理器(Handler)。

public class HitTrackingHandlerFactory: IHttpHandlerFactory
{
   public HitTrackingHandlerFactory()
   {
   }

   public virtual IHttpHandler GetHandler(HttpContext context,
     String requestType, String url, String pathTranslated)
   {

     if (!HitLogHelper.CheckHitCount(context.Request.UserHostAddress, context.Request.UserHostName))
        return new HitsExceededHandler();
       
     Object handler = null;
  
     try
     {
        String filename = url.Substring(url.LastIndexOf('/')+1);
        String file = filename.Substring(0, filename.IndexOf('.'));
        String ext = filename.Substring(filename.LastIndexOf('.')+1);

        if (ext == "aspx")
        {
           return System.Web.UI.PageParser.GetCompiledPageInstance(url, pathTranslated, context);
        }
        else if (ext == "asmx")
        {
           System.Web.Services.Protocols.WebServiceHandlerFactory fact = new
                        System.Web.Services.Protocols.WebServiceHandlerFactory();
    
           handler = fact.GetHandler(context, context.Request.RequestType, url, pathTranslated);
        }
        else if (ext == "rem")
        {
           System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory fact = new
                        System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory();
           handler = fact.GetHandler(context, context.Request.RequestType, url, pathTranslated);
        }
        else
        {
          throw new HttpException("Unable to process extension *." + ext);
        }

     }
     catch (Exception e)
     {
        throw new HttpException("HitTrackingHandlerFactory", e);
     }
     return (IHttpHandler)handler;
   }


   public virtual void ReleaseHandler(IHttpHandler handler)
   {
     return;
   }
}

public class HitsExceededHandler: IHttpHandler
{
   public HitsExceededHandler()
   {
   }

   public virtual void ProcessRequest(HttpContext context)
   {
     context.Response.Write("<h1>Number of hits exceeded!</h1><p>");
   }
   
   public virtual bool IsReusable
   {
     get { return true; }
   }
}


实现IHttpModule接口
模块提供了一种与应用程序事件以及HTTP请求和响应对象交互的事件驱动模式。注册模块是在Http处理器和处理工厂前被实例化的,所以自身能够注册(绑定)应用程序事件。事实上,模块与Web应用程序通过两种方式组合:监听应用程序事件并且触发与之绑定的应用程序事件的自定义事件。后者与应用程序模块紧密结合。在一个组件的独立部分,提交域(former)提供了访问Http请求、响应、会话状态对象的多种方式。
创建一个自定义模块意味着创建一个实现IHttpModule接口的.Net组件,这个接口具有以下成员:
Init()            提供了一个为模块注册(绑定)应用程序事件的恰当时机。
Dispose()    提供了一个清除对资源分派(对象)的恰当时机。
在下面这个例子种,Init()方法为HttpApplication对象注册(绑定)了PreRequestHandlerExecute, PostRequestHandlerExecute, and Error事件。

protected void Init()
{
  application.PreRequestHandlerExecute +=
(new EventHandler(this.Application_PreRequestHandlerExecute)); 
   application.PostRequestHandlerExecute +=
(new EventHandler(this.Application_PostRequestHandlerExecute));
   application.Error += (new EventHandler(this.Application_Error));
}


你也可以在Global.asax文件中对一个独立应用程序进行这些事件处理。无论怎样,使用模块使得能够配置多个应用程序处理的通用化的事件集合。
<httpModules>
   <add name="EventModule" type="WebHandlers.EventModule,WebHandlers"/>
   <add name="ErrorHandlerModule" type="WebHandlers.ErrorHandlerModule,WebHandlers"/>
</httpModules>
在这个全局错误处理器(Global Error Handler)中,你能够提供一种捕获所有错误操作并且提示站点管理者一些未捕获异常信息的方式。

处理器与模块
从架构的角度看,处理器和模块有着不同的用途。处理器(包括处理工厂方法调用返回的处理器)提供了一种截获请求以及如何改变请求(请求路由)的途径。模块对于以上方法一样可以做到,并且可以发送自定义的响应以及取消这些任务的操作。这些使得他们具有了访问HttpApplication,HttpReuqst,HttpResponse,HttpSessionState对象的能力以便你能够熟练的与数据进行交互。
以下是组件事件发生的顺序:
1、HttpApplication对象被创建(如果需要)
2、HttpModule对象被创建(以配置文件中声明的次序)
3、模块接收请求并且验证请求的正确性,之后优先的控件将会先传递给处理器处理
4、返回的对象被创建(如:Page, Web Service 或 Remote object)
5、这些对象,应用程序以及模块继续通过其他的事件彼此交互
下面的图标阐明了这个过程以及它们实例化的次序:

接下来的图表阐明了处理工厂,处理器以及其他扩张在整个工作流程中的位置:



全文完!

posted on 2005-03-28 16:11 Bluefee.Net 阅读(...) 评论(...) 编辑 收藏