ASP.NET MVCのいくつかのActionResultの本質:FileResult

37383 ワード

FileResultはファイルベースのActionResultであり、FileResultを利用すると、ある物理ファイルからのコンテンツをクライアントに簡単に応答することができます.ASP.NET MVCは、FileContentResult、FilePathResult、FileStreamResultの3つの特定のFileResultを定義します.この記事では、3つの具体的なFileResultがファイルの内容をリクエストにどのように応答するかについて検討します.[本文は『How ASP.NET MVC Works?』に同期しました.]
ディレクトリ1、FileResult 2、FileContentResult 3、FilePathResult 4、FileStreamResult 5、インスタンスプレゼンテーション:FileResultによるピクチャのパブリッシュ
一、FileResult
次のコード・スライスに示すように、FileResultは、コンストラクション関数で初期化されたメディア・タイプを表す読み取り専用属性ContentTypeを有する.物理ファイルに基づいて対応するFileResultオブジェクトを作成する場合は、ターゲットファイルが1つであるなど、ファイルの種類に応じてメディアタイプを指定する必要があります.jpgピクチャは、対応するメディアタイプが「image/jpeg」である、1つについてである.pdfファイルは、「アプリケーション/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: }
ファイルに対する応答は、インラインと添付ファイルの2つの形式を有する.一般的に、前者はブラウザを使用して応答するファイルを直接開き、後者は独立したファイルでクライアントにダウンロードします.後者の場合、ダウンロードしたファイルのファイル名を指定します.このファイル名は、FileResultのFileDownloadNameプロパティで指定できます.ファイル応答はデフォルトではインライン化されており、添付ファイルの形式が必要な場合は、応答の名前が「attachment;filename={FileDownloadName}」のContent-Dispositionのヘッダを作成する必要があります.
FileResultは単なる抽象クラスであり、ファイルコンテンツの出力は、書き換えられたExecuteResultメソッドで呼び出される抽象メソッドWriteFileに実装される.FileDownloadNameプロパティが空でない場合は、添付ファイルとしてファイル応答が行われることを意味し、FileResultは書き換えられたExecuteResultメソッドでContent-Disposition応答ヘッダの設定を行います.次のようなコード断片は、FileResultにおけるExecuteResultメソッドの実装を実質的に体現している.
   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は、FileContentResult、FilePathResult、FileStreamResultの3つの具体的なFileResultを定義しています.次に、それらを個別に説明します.

二、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では、上記の2つのFileリロードが、指定したバイト配列、メディアタイプ、およびダウンロードファイル名(オプション)に基づいて対応するFileContentResultを生成するように定義されています.FileContentResultはバイト配列に基づいて作成されるため、物理ファイルから読み込むのではなく応答ファイルの内容を動的に生成する必要がある場合、FileContentResultは良い選択です.

三、FilePathResult


名前から分かるように、FilePathResultは物理ファイルパスに基づいてFileResultを作成します.次のコード断片に示すように、応答ファイルを表すパスは、コンストラクション関数で初期化された読み取り専用プロパティFileNameで表されます.実装されたWriteFileメソッドでは、FilePathResultは、現在のHttpResponseのTransmitFileをパラメータとして直接ファイルパスを呼び出し、ファイルコンテンツに対する応答を実現する.抽象クラスControllerは、ファイルパスに基づいて適切なFilePathResultを作成するために、2つのFileメソッドの再ロードを定義します.
   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では、ファイル読み出しストリームに基づいて対応するFileStreamResultを作成する2つのFileメソッドが同様に定義されています.
   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枚のピクチャを1つのリストで表示する.ピクチャの要素に基づく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{width: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枚の画像が下の図のような効果でブラウザに表示されます.