65.9K
CodeProject 正在变化。 阅读更多。
Home

定制文本文件 .NET HTTP 处理器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (3投票s)

2002 年 9 月 16 日

2分钟阅读

viewsIcon

91068

downloadIcon

543

定制文本文件 .NET HTTP 处理器,用于处理不带标准扩展名的文本文件,例如 .aaa、.xxx。

引言

本例提供了一个简单的高性能 .NET HTTP 定制处理器,用于处理文本文件的浏览请求。在许多情况下,网站需要处理没有标准扩展名的文本文件,*.txt,但 IIS 无法识别此类文本文件,这给我们带来了很多麻烦!这个简单的 HTTP 文本文件处理器可以使用非标准扩展名读取文件,并使用异步 IO。

步骤 1

通过实现 HTTP 处理器接口 IHttpHandler 来创建 HTTP 处理器程序

using System ;
using System.IO ;
using System.Web ;
using System.Text ; 

namespace Matthew.Utility
{

 public class FileHandler : IHttpHandler {


  private const int RD_BUFFER_SIZE = 4*1024 ;
  private HttpResponse Response ;
  private HttpRequest Request ;


  // State for Async read

  public class StateObject {
     public byte[] bs ;
     public FileStream fs ;
  }

  public void ProcessRequest(HttpContext ctx) {

    Response = ctx.Response ;
    Request = ctx.Request ;

    String Filename = Request.FilePath ;

    if ( Filename != null ) {

        Filename = Request.MapPath(Filename) ;
        FileStream fs = null ;

        try {
            fs = File.Open(Filename , 
              FileMode.Open, FileAccess.Read, FileShare.Read) ;
        }
        catch (  FileNotFoundException  ) {
            Response.Write("<html><body><h2>File <i>" + 
                Request.FilePath + 
                "</i> not exists!</h2></body></html>" ) ;
            return ;
        }

        StateObject stateObject = new StateObject() ;

        stateObject.fs = fs ;
        stateObject.bs = new byte[RD_BUFFER_SIZE] ;

        //  Set the content type as the browser need to know

        // how to display the content bases on its type

        Response.ContentType = "Text/plain" ;

        // Begin Async file read

         fs.BeginRead( stateObject.bs, 0, RD_BUFFER_SIZE, 
           new AsyncCallback(this.ReadCallback), stateObject );

    }
  } // void ProcessRequest(HttpContext ctx)



  public bool IsReusable { get { return true ; } }


  public void ReadCallback(IAsyncResult asyncResult)  {

    StateObject stateObject = (StateObject) asyncResult.AsyncState;

    FileStream fs = stateObject.fs;//(Stream) asyncResult.AsyncObject;


    int bytesRead = fs.EndRead(asyncResult);

    // Stream only return zero (0) at the end of the stream

    if ( bytesRead != 0 )  {  
        Response.BinaryWrite(stateObject.bs) ;
          fs.BeginRead( stateObject.bs, 0, RD_BUFFER_SIZE, 
            new AsyncCallback(this.ReadCallback), stateObject );
    }
    else {
           fs.Close() ;
    }

  }


 } // Class

} // namespace

并将程序编译到 Web 应用程序虚拟目录的 /bin 子目录中。

第二步

修改 Web 应用程序虚拟目录中的 .NET 应用程序配置文件 web.config,如下所示

<configuration>
    <system.web>
    <httpHandlers>
        <add verb="*" path="*.aaa" 
          type="Matthew.Utility.FileHandler,TextDocHandler" />
    </httpHandlers>
    </system.web>   
</configuration>

在本例中,文件扩展名 .aaa 被选择由程序集 TextDocHandler 中的类 Matthew.Utility.FileHandler 处理。

步骤 3

将您的目标文本文件扩展名 .aaa 的应用程序映射添加到 IIS 元数据库中,以便在 IIS 收到 URL 路径中此类文件扩展名时,通知 IIS 服务将请求传递给 .NET。在我的例子中,.NET 库是 H:\WINNT\Microsoft.NET\Framework\v1.0.3705\aspnet_isapi.dll,您必须将您的文件扩展名映射到您的 .NET 模块,这可能与我的模块的位置不同。这就是安装定制文本文件处理器所要做的全部!

简单测试

创建一个新的文本文件,命名为 test.aaa,并将其放置在您的 Web 虚拟目录下。当您输入链接 https:///ASP.NET/test.aaa,这里我的虚拟目录是 ASP.NET,您应该在浏览器上看到文本文件显示(请记住先启动您的 IIS 服务!)。要测试当文件不存在时会发生什么,请尝试 https:///ASP.NET/test1.aaa,并且处理器程序将显示一条错误消息,您可以确定您的 HTTP 处理器实际上正在控制以响应请求。尝试显示一个非常大的文本文件,异步方法将在读取一些数据后立即在浏览器上显示部分文件。这将提供更好的响应式用户体验!

结论

借助新的 .NET HTTP 处理器定制功能,我们可以轻松地添加文本文件处理器等功能,而不会出现任何问题!文本处理器只是我抛砖引玉的一个简单例子,您可以创建更复杂的 HTTP 处理器来处理更多不同类型的文件,而限制是您的想象力!

© . All rights reserved.