好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

了解ASP.NET MVC几种ActionResult的本质:FileResult

了解ASP.NET MVC几种ActionResult的本质:FileResult

FileResult 是一个基于文件的ActionResult,利用FileResult我们可以很容易地将从某个物理文件的内容响应给客户端。ASP.NET MVC定义了三个具体的FileResult,分别是FileContentResult、FilePathResult和FileStreamResult。在这篇文章中我们将探讨三种具体的FileResult是如何将文件内容对请求进行响应的。[本文已经同步到《 How ASP.NET MVC Works? 》中]

目录 
一、FileResult 
二、FileContentResult 
三、FilePathResult 
四、FileStreamResult 
五、实例演示:通过FileResult发布图片

一、FileResult

如下面的代码片断所示,FileResult具有一个表示媒体类型的只读属性ContentType,该属性在构造函数中被初始化。当我们基于某个物理文件创建相应的FileResult对象的时候应该根据文件的类型指定媒体类型,比如说目标文件是一个.jpg图片,那么对应的媒体类型为“image/jpeg”,对于一个.pdf文件,则采用“application/pdf”。

    1:   public   abstract   class  FileResult : ActionResult
    2:  {    
    3:       protected  FileResult( string  contentType);
    4:       public   override   void  ExecuteResult(ControllerContext context);
    5:       protected   abstract   void  WriteFile(HttpResponseBase response);
    6:      
    7:       public   string  ContentType { get; }
    8:       public   string  FileDownloadName { get; set; }   
    9:  }

针对文件的响应具有两种形式,即内联(Inline)和附件(Attachment)。一般来说,前者会利用浏览器直接打开响应的文件,而后者会以独立的文件下载到客户端。对于后者,我们一般会为下载的文件指定一个文件名,这个文件名可以通过FileResult的FileDownloadName属性来指定。文件响应在默认情况下采用内联的方式,如果需要采用附件的形式,需要为响应创建一个名称为Content-Disposition的报头,该报头值的格式为“attachment; filename={ FileDownloadName }”。

FileResult仅仅是一个抽象类,文件内容的输出实现在抽象方法WriteFile中,该方法会在重写的ExecuteResult方法中调用。如果FileDownloadName属性不为空,意味着会采用附件的形式进行文件响应,FileResult会在重写的ExecuteResult方法中进行Content-Disposition响应报头的设置。如下面的代码片断基本上体现了ExecuteResult方法在FileResult中的实现。

    1:   public   abstract   class  FileResult : ActionResult
    2:  {
    3:       //其他成员 
    4:       public   override   void  ExecuteResult(ControllerContext context)
    5:      {        
    6:          HttpResponseBase response = context.HttpContext.Response;
    7:          response.ContentType =  this .ContentType;
    8:           if  (! string .IsNullOrEmpty( this .FileDownloadName))
    9:          {
   10:               //生成Content-Disposition响应报头值 
   11:               string  headerValue = ContentDispositionUtil.GetHeaderValue( this .FileDownloadName);
   12:              context.HttpContext.Response.AddHeader( "Content-Disposition" , headerValue);
   13:          }
   14:           this .WriteFile(response);
   15:      }
   16:  }

ASP.NET MVC定义了三个具体的FileResult,分别是FileContentResult、FilePathResult和FileStreamResult,接下来我们对它们进行单独介绍。

二、FileContentResult

FileContentResult 是针对文件内容创建的FileResult。如下面的代码片断所示,FileContentResult具有一个字节数组类型的只读属性FileContents表示响应文件的内容,该属性在构造函数中指定。FileContentResult针对文件内容的响应实现也很简单,从如下所示的WriteFile方法定义可以看出,它只是调用当前HttpResponse的OutputStream属性的Write方法直接将表示文件内容的字节数组写入响应输出流。

    1:   public   class  FileContentResult : FileResult
    2:  {
    3:       public   byte [] FileContents { get; }
    4:       public  FileContentResult( byte [] fileContents,  string  contentType) ;
    5:   
    6:       protected   override   void  WriteFile(HttpResponseBase response)
    7:      {
    8:          response.OutputStream.Write( this .FileContents, 0,  this .FileContents.Length);
    9:      }    
   10:  }
   11:   
   12:   public   abstract   class  Controller : ControllerBase, ...
   13:  {
   14:       // 其他成员    
   15:       protected  FileContentResult File( byte [] fileContents,  string  contentType);
   16:       protected   virtual  FileContentResult File( byte [] fileContents,  string  contentType,  string  fileDownloadName);
   17:  }

抽象类Controller中定义了如上两个File重载根据指定的字节数组、媒体类型和下载文件名(可选)生成相应的FileContentResult。由于FileContentResult是根据字节数组创建的,当我们需要动态生成响应文件内容(而不是从物理文件中读取)时,FileContentResult是一个不错的选择。

三、FilePathResult

从名称可以看出, FilePathResult 是一个根据物理文件路径创建FileResult。如下面的代码片断所示,表示响应文件的路径通过只读属性FileName表示,该属性在构造函数中被初始化。在实现的WriteFile方法中,FilePathResult直接将文件路径作为参数调用当前HttpResponse的TransmitFile实现了针对文件内容的响应。抽象类Controller同样定义了两个File方法重载来根据文件路径创建相应的FilePathResult。

    1:   public   class  FilePathResult : FileResult
    2:  {
    3:       public   string  FileName { get; }
    4:       public  FilePathResult( string  fileName,  string  contentType);
    5:   
    6:       protected   override   void  WriteFile(HttpResponseBase response)
    7:      {
    8:          response.TransmitFile( this .FileName);
    9:      }    
   10:  }
   11:   
   12:   public   abstract   class  Controller : ControllerBase, ...
   13:  {
   14:       //其他成员 
   15:       protected  FilePathResult File( string  fileName,  string  contentType);
   16:       protected   virtual  FilePathResult File( string  fileName,  string  contentType,  string  fileDownloadName);
   17:  }


四、FileStreamResult

FileStreamResult 允许我们通过一个用于读取文件内容的流来创建FileResult。如下面的代码片断所示,读取文件流通过只读属性FileStream表示,该属性在构造函数中被初始化。在实现的WriteFile方法中,FileStreamResult通过指定的文件流读取文件内容,并最终调用当前HttpResponse的OutputStream属性的Write方法将读取的内容写入当前HTTP响应的输出流中。抽象类Controller中同样定义了两个File方法重载根据文件读取流创建相应的FileStreamResult。

    1:   public   class  FileStreamResult : FileResult
    2:  {
    3:       public  Stream FileStream { get; }
    4:       public  FileStreamResult(Stream fileStream,  string  contentType);    
    5:   
    6:       protected   override   void  WriteFile(HttpResponseBase response)
    7:      {
    8:          Stream outputStream = response.OutputStream;
    9:           using  ( this .FileStream)
   10:          {
   11:               byte [] buffer =  new   byte [0x1000];
   12:               while  ( true )
   13:              {
   14:                   int  count =  this .FileStream.Read(buffer, 0, 0x1000);
   15:                   if  (count == 0)
   16:                  {
   17:                       return ;
   18:                  }
   19:                  outputStream.Write(buffer, 0, count);
   20:              }
   21:          }
   22:      }    
   23:  }
   24:   
   25:   public   abstract   class  Controller : ControllerBase, ...
   26:  {
   27:       //其他成员 
   28:       protected  FileStreamResult File(Stream fileStream,  string  contentType);
   29:       protected   virtual  FileStreamResult File(Stream fileStream,  string  contentType,  string  fileDownloadName);
   30:  }


五、实例演示:通过FileResult发布图片

为了让读者对FileResult具有更加深刻地认识,我们通过一个实例来演示如何通过FileResult来对外发布图片。在通过Visual Studio的ASP.NET MVC项目模板创建的空Web应用中,我们在根目录下添加一个名为images的子目录来存放发布的.jpg图片,然后我们定义如下一个HomeController。

    1:   public   class  HomeController : Controller
    2:  {
    3:       public  ActionResult Index()
    4:      {
    5:           return  View();
    6:      }
    7:   
    8:       public  ActionResult Image( string  id)
    9:      {
   10:           string  path = Server.MapPath( "/images/"  + id +  ".jpg" );
   11:           return  File(path,  "image/jpeg" );
   12:      }
   13:  }

图片的发布体现在Action方法Image上,表示图片ID的参数同时作为图片的文件名(不含扩展名)。在该方法中,我们根据图片ID解析出对应文件的路径后,直接调用File方法创建一个媒体类型为“image/jpeg”的FilePathResult。在Action方法Index中呈现的View定义如下,我们通过一个列表显示6张图片。基于图片的<img>元素的src属性指定的地址正是指向定义在HomeController的Action方法Image,指定的表示图片ID的参数分别是001、002、…、006。

    1:   <  html  > 
    2:       <  head  > 
    3:           <  title  > Gallery </  title  > 
    4:           <  style   type  ="text/css"  > 
    5:              li{list-style-type:none; float:left; margin:10px 10px 0px 0px;}
    6:              img{100px; height:100px;}
    7:           </  style  > 
    8:       </  head  > 
    9:       <  body  > 
   10:           <  ul  > 
   11:               <  li  ><  img   alt  ="001"   src  ="@Url.Action("  Image  ", new { id = "  001  " })"  /></  li  > 
   12:               <  li  ><  img   alt  ="002"   src  ="@Url.Action("  Image  ", new { id = "  002  " })"  /></  li  > 
   13:               <  li  ><  img   alt  ="003"   src  ="@Url.Action("  Image  ", new { id = "  003  " })"  /></  li  > 
   14:               <  li  ><  img   alt  ="004"   src  ="@Url.Action("  Image  ", new { id = "  004  " })"  /></  li  > 
   15:               <  li  ><  img   alt  ="005"   src  ="@Url.Action("  Image  ", new { id = "  005  " })"  /></  li  > 
   16:               <  li  ><  img   alt  ="006"   src  ="@Url.Action("  Image  ", new { id = "  006  " })"  /></  li  > 
   17:   
   18:           </  ul  > 
   19:       </  body  > 
   20:   </  html  > 

我们将6张.jpg图片存放到/imges目录下,并分别命名为001、002、…、006。直接运行程序之后这6张图片会以如下图所示的效果显示在浏览器上。

作者: Artech
出处: http://artech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于了解ASP.NET MVC几种ActionResult的本质:FileResult的详细内容...

  阅读:45次