图片查看器处理程序

  为加快处理速度,IIS会直接处理Web应用程序中的某些静态资源,而不会调用ISAPI扩展。这些静态文件包括图像和HTML文件。如果从浏览器直接请求gif或jpg文件,IIS会获取指定的资源,正确设置响应缓冲的内容类型,并将其输出成文件的字节流.

  如果浏览器地址指向包含多个图像的虚拟目录呢?在这种情况下,IIS无法识别文件夹的内容,而可能只返回文件的列表。

  那么如何实现指向该虚拟目录地址,在浏览器中显示该目录下图片的预览呢?

图片查看器HTTP处理程序的设计

  首先,需要确定如何使IIS知道我们的意图?可以通过在文件夹名称后追加一个特定的端点,使IIS将请求传给ASP.NET,由ASP.NET来提供其中图像的预览。换言之,这个思路是,将图片查看器处理程序与一个特定的端点(如folder.axd)绑定。固定端点所指向的不必一定是已经存在的、已部署好的资源,将folder.axd追加到文件夹名之后即可。如下地址所示:

  http://www.contoso.com/images/folder.axd

  处理程序此时要做的是,提取URL中文件夹名,并选出其中的图片以预览。

  在ASP.NET中,axd扩展名通常用于引用特殊服务。用于跟踪的Trace.axd,及用于插入脚本和资源的WebResource.axd,都是使用该扩展名的典型案例。

图片查看器HTTP处理程序的实现

  图片查看器处理程序要返回一个包含指定文件夹中所有图像的多列表格。该类的结构如下:




class 
    PictureViewerInfo
{
 
   public 
    PictureViewerInfo()
 {
 DisplayWidth  
   = 
     
   200 
   ;
 ColumnCount  
   = 
     
   3 
   ;
 }

 
   public 
     
   int 
    DisplayWidth;
 
   public 
     
   int 
    ColumnCount;
 
   public 
     
   string 
    FolderName;
}

 
   public 
     
   class 
    PictureViewerHandler : IHttpHandler
{
 
   public 
     
   void 
    ProcessRequest(HttpContext context)
 {
 PictureViewerInfo info  
   = 
    GetFolderInfo(context);
 
   string 
    html  
   = 
    CreateOutput(info);

 
   // 
   Output the data 
   
 
    context.Response.Write( 
   " 
   <html><head><title> 
   " 
   );
 context.Response.Write( 
   " 
   Picture Web Viewer 
   " 
   );
 context.Response.Write( 
   " 
   </title></head><body> 
   " 
   );
 context.Response.Write(html);
 context.Response.Write( 
   " 
   </body></html> 
   " 
   );
 }

 
   public 
     
   bool 
    IsReusable
 {
 
   get 
    {  
   return 
     
   true 
   ; }
 }
 ...
}



  为获取实际的路径,只需从URL中去除“folder.axd”字符串及所有斜杠和反斜杠。随后,我们将文件夹的URL映射到服务器的路径,通过.NET Framework进行处理。




private 
    ArrayList GetAllImages( 
   string 
    path)
{
 
   string 
   [] fileTypes  
   = 
    {  
   " 
   *.bmp 
   " 
   ,  
   " 
   *.gif 
   " 
   ,  
   " 
   *.jpg 
   " 
   ,  
   " 
   *.png 
   " 
    );
 ArrayList Images  
   = 
     
   new 
    ArrayList();
 DiectoryInfo di  
   = 
     
   new 
    DirectoryInfo(path);
 
   foreach 
   ( 
   string 
    ext  
   in 
    fileTypes)
 {
 FileInfo[] files  
   = 
    di.GetFiles(ext);
 
   if 
   (files.Length  
   > 
     
   0 
   )
 images.AddRange(files);
 }
 
   return 
    images;
}



  输出图片预览:




string 
    CreateOutputForFolder(PictureViewerInfo info)
{
 ArrayList images  
   = 
    GetAllImages(info.FolderName);
 Table t  
   = 
     
   new 
    Table();

 
   int 
    index  
   = 
     
   0 
   ;
 
   bool 
    moreImages  
   = 
     
   true 
   ;
 
   while 
   (moreImages)
 {
 TableRow row  
   = 
     
   new 
    TableRow();
 t.Rows.Add(row);
 
   for 
   ( 
   int 
    i  
   = 
     
   0 
   ; i  
   < 
    info.ColumnCount; i 
   ++ 
   )
 {
 TableCell cell  
   = 
     
   new 
    TableCell();
 row.Cells.Add(cell);

 
   // 
   Create the image 
   
 
    Image img  
   = 
     
   new 
    Image();
 FileInfo fi  
   = 
    (FileInfo)images[index];
 img.ImageUrl  
   = 
    filName;
 img.Width  
   = 
    Unit.Pixel(info.DisplayWidth);

 
   // 
   Wrap the image in an anchor so tha a larger image is 
 
   // 
   shown when the user clicks 
   
 
    HtmlAnchor a  
   = 
     
   new 
    HtmlAnchor();
 a.Href  
   = 
     
   new 
    HtmlAnchor(); 
  
 a.Controls.Add(img);
 cell.Controls.Add(a);

 
   // 
   Check whether there are more images to show 
   
 
    index 
   ++ 
   ;
 moreImages  
   = 
    (index  
   < 
    images.Count);
 
   if 
   ( 
   ! 
   moreImage)
 
   break 
   ;
 }
 } 
  
string html = Utils.RenderControlAsString(t);
    return html; 
}



  我们可使该处理程序接受一些可选的查询字符串参数(如图像宽度和列数)。下面是处理URL查询字符串的过程:




PictureViewerInfo info  
   = 
     
   new 
    PictureViewInfo();
 
   object 
    p1  
   = 
    context.Request.Params[ 
   " 
   Width 
   " 
   ];
 
   object 
    p1  
   = 
    context.Request.Params[ 
   "" 
   ];

  下面是处理URL查询字符串的过程:



PictureViewerInfo  
   = 
     
   new 
    PictureViewerINfo();
 
   object 
    p1  
   = 
    context.request.Params[ 
   " 
   Width 
   " 
   ];
 
   object 
    p2  
   = 
    context.request.Params[ 
   " 
   Cols 
   " 
   ];
 
   if 
   (p1  
   != 
     
   null 
   )
 Int32.TryParse(( 
   string 
   )p1,  
   out 
    info.DisplayWidth);
 
   if 
   (p1  
   != 
     
   null 
   )
 Int32.TryParse(( 
   string 
   )p2,  
   out 
    info.ColumnCount);

  该处理程序的注册非常简单,将以下脚本添加到web.config即可:



< 
   add verb 
   = 
   " 
   * 
   " 
    path 
   = 
   " 
   folder.axd 
   " 
    type 
   = 
   " 
   Core35.Components.PictureViewerHandler, Core35Lib 
   " 
     
   />



  将生成的程序集置于GAC中,并将这段脚本插入到全局的web.config中,那么当前计算机中所有的应用程序都可共享该功能了。

  使用示例:

命令查看处理器架构_命令查看处理器架构