上一篇讲到IHttpModule,以及在HttpModule中响应的一系统事件的顺序,在HttpHandler之前,有各种的HttpModule,可以在这些模块的响应事件中处理我们自己的逻辑,

而HttpHandler才是真正的服务器端进行请求处理的实现,这篇就是对HttpHandler进行一个总结。

 

首先在.Net 2.0,找到C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\ 目录下的web.config 文件,找到httpHandlers结点,应该可以看到如下这样的配置.

<httpHandlers> 
<add path="*.axd" verb="*" type="System.Web.HttpNotFoundHandler" validate="True" /> 
<add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" /> 
<add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True" /> 
<add path="*.asax" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" /> 
<add path="*.ascx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" /> 
<add path="*.config" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" /> 
<add path="*.cs" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" /> 
<add path="*" verb="GET,HEAD,POST" type="System.Web.DefaultHttpHandler" validate="True" /> 
</httpHandlers>

 

可以看到,<httpHandlers>结点中将不同的文件类型映射给不同的Handler去处理,于.aspx来说,由 System.Web.UI.PageHandlerFactory来处理。而对于.cs来说,是由 System.Web.HttpForbiddenHandler处理,ForbiddenHandler名字中出现的Forbidden (翻译过来是"禁止")可以看出,个Handler可以避免我们的源码被看到,而PageHandlerFactory类是 ASP.NET 页的默认处理程序工厂实现,继承的是IHttpHandlerFactory接口,IHttpHandlerFactory后面会再讲.

在Asp.Net中有这样一种文件扩展名为ashx,叫"一般处理文件",这个文件就是继承IHttphandler接口,是一种完全自定义的处理Http请求的文件.

 

现在写个小例子,通过继承IHttphandler来实现.

public class HttpGetData : IHttpHandler
{
   public void ProcessRequest(HttpContext context)   //处理请求的方法
    { 
       if (context.Request.Params.Count > 0) 
        { 
            string id = string.Empty; 
            string tableName = string.Empty; 
            if (context.Request["id"] != null) 
            { 
                id = context.Request["id"]; 
            } 
            if (context.Request["tableName"] != null) 
            { 
               tableName = context.Request["tableName"]; 
            } 

            string sql = string.Format("select [code],[name] from {0} where FID='{1}'", tableName, id); 
            DataSet ds = DBHelperToSql.QueryData(sql);  //获取数据 
              string FormatStr = string.Empty; 
            foreach (DataRow row in ds.Tables[0].Rows) 
                FormatStr += "$" + row.ItemArray[0].ToString() + row.ItemArray[1].ToString(); 
            FormatStr = FormatStr.Substring(1); 
            context.Response.Write(FormatStr);  //返回响应数据 
              context.Response.End(); 
        } 
        else 
        { 
            context.Response.Write("禁止非法访问此页面!"); 
            context.Response.End(); 
        } 
    } 

    public bool IsReusable 
    { 
        get { return ture; } 
    } 
}

 

JS代码:

function AjaxRequstFn(FID, id, tableName) { 
    $.ajax({ 
        type: 'GET', 
        url: 'HttpGetData.ashx',//向HttpGetData.ashx请求,在HttpGetData.ashx进行请求处理 
         processData: false, 
        dataType: 'text', 
        data: 'id=' + escape($('#' + FID).val()) + '&tableName=' + tableName, 
        success: function(data, textStatus) { 
            FormatData(data, id); //格式化字符串 
        }, 
        error: function(XMLHttpRequest, textStatus, errorThrown) { 
            $('#showResult').html(ErrorMessage); 
        } 
    }); 
}

//格式化字符串 
function FormatData(data, id) { 
    var items = data.split('$'); 
    var value = ''; 
    var text = ''; 
    for (var i = 0; i < items.length; i++) { 
        value = items[i].substr(0, 6); 
        text = items[i].substr(6, items[i].length); 
        $('#' + id).append('<option value="' + value + '">' + text + '</option>'); 
    } 
    $('#' + id).removeAttr('disabled'); 
}

Html代码:

<select id="SelProvince"> 
</select>&nbsp;&nbsp;&nbsp;&nbsp; 
<select id="SelCity" disabled="disabled"> 
   <option value="请选择城市">==请选择城市==</option> 
</select>&nbsp;&nbsp;&nbsp;&nbsp; 
<select id="SelArea" disabled="disabled"> 
   <option value="请选择地区">==请选择地区==</option> 
</select>

 

上述例子就是通过前台ajax请求,然后在后台进行HttpHandler,之后返回前台再进行数据转化再展示.是一个完整的Http请求的流程.

当然在我的上述例子中没有用到Session,如果在Http请求类中需要使用Session, 那仅需要实现 IHttpHandler接口(这个显然),为了在这个Handler类中使用SessionState,

还需要实现 IRequiresSessionState接口,对于这个接口,MSDN的解释是这样的:Specifies that the target HTTP handler requires read and write access to session-state values. This is a marker interface and has no methods.(翻译过来是:指定当前Http Handler需要对SessionState值的读写访问权。这是一个标记接口,没有任何方法)。

 

IRequiresSessionState的接口定义是这样的:

public interface IRequiresSessionState{}

 

当然你也可以不使用ashx文件,直接定义类去继承IHttpHandler,如果是这样,还需要在web.config当中去设置.例如:

  <system.web>
    <httpHandlers>
      <add path="*.jpg" verb="*" type="MyCustomHandler.JpgHandler, MyCustomHandler" />
    </httpHandlers>
</system.web>

 

下面说下IHttpHandlerFactory,实现 IHttpHandlerFactory 接口的类是为了动态创建实现 IHttpHandler 接口的类的新实例

public class MyFactory : IHttpHandlerFactory
{
    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
     public virtual IHttpHandler GetHandler(HttpContext context, 
                                             String requestType, 
                                             String url, 
                                             String pathTranslated)
     {
         String fname = url.Substring(url.LastIndexOf('/')+1);
         String cname = fname.Substring(0, fname.IndexOf('.'));
         String className = "test." + cname;

         Object h = null;

         // Try to create the handler object.
         try 
         {
            // Create the handler by calling class abc or class xyz.
            h = Activator.CreateInstance(Type.GetType(className));
         }
         catch(Exception e)
         {
            throw new HttpException("Factory couldn't create instance " +
                                    "of type " + className, e);
         }
         return (IHttpHandler)h;
     }

      // This is a must override method.
     public virtual void ReleaseHandler(IHttpHandler handler)
     {

     }
 }
 
<configuration> 
  <system.web> 
    <httpHandlers> 
      <add verb="*" path="abc.aspx,xyz.aspx" type="test.MyFactory,HandlerFactoryTest" /> 
    </httpHandlers> 
  </system.web>
</configuration>

posted on 2013-09-23 14:28  tzj19810812  阅读(524)  评论(0编辑  收藏  举报