メイン画像

ASP.NET Web API - ファイルをダウンロードして表示する方法

ASP.NET Web API - ファイルをダウンロードして表示する方法


ASP.NET Web API でダウンロードさせたファイルを表示する方法を紹介する。

サンプルとして、リンクをクリックされたら、新しいタブにリンク先のファイル(PDF を想定)を表示するプログラムを使う。

確認環境

  • ASP.NET Web API 2.2

サンプルプログラム(Web API)

次の Web API は、クエリ文字列で指定されたファイル名に該当するファイルを応答として返す。

GET メソッドで URL “~/api/files/download” で呼び出せるよう、属性ルーティングで設定してある。

[RoutePrefix("api/files")]
public class FilesController : ApiController
{
    [HttpGet]
    [Route("download")]
    public IHttpActionResult Download(string fileName)
    {
        // ファイル名の指定がなければ 400 エラー
        if (string.IsNullOrEmpty(fileName))
        {
            return BadRequest();
        }

        // ファイルパスを生成
        // ここでは App_Data の配下にファイルがあるものとする
        var path = System.IO.Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data"), fileName);

        // ファイルが存在しなければ 404 エラー
        if (!System.IO.File.Exists(path))
        {
            return NotFound();
        }

        // ファイルをバイト配列に読み取る
        var fileBytes = System.IO.File.ReadAllBytes(path);

        // 読み取った内容を応答メッセージに設定
        var res = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.OK)
        {
            Content = new System.Net.Http.ByteArrayContent(fileBytes),
        };

        // Content-Type を設定
        res.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");

        // Content-Disposition を設定
        res.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("inline")
        {
            FileNameStar = fileName,
        };

        return ResponseMessage(res);
    }
}

解説

ファイルが存在しないなら 404 を返す。
アクセスできない場所に保存されている場合もここで処理される。

if (!System.IO.File.Exists(path))
{
    return NotFound();
}

 

ファイルが存在するなら、次の手順でファイルの内容を応答に設定して返す。

  1. ファイルをバイト配列に読み取り、応答に設定

    HttpResponseMessage クラスの Content プロパティが応答の内容。

    // ファイルをバイト配列に読み取る
    var fileBytes = System.IO.File.ReadAllBytes(path);
    
    // 読み取った内容を応答メッセージに設定
    var res = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.OK)
    {
        Content = new System.Net.Http.ByteArrayContent(fileBytes),
    };
  2. Content-Type ヘッダーにファイル種別を表す MIME タイプを設定

    サンプルは PDF ファイルを想定するため application/pdf を設定している。

    res.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");

    ちなみに Content-Type を未設定にしたら、ウェブページには PDF ファイルのバイナリデータがそのまま表示された。

  3. Content-Disposition ヘッダーに inline を設定

    res.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("inline")
    {
        FileNameStar = fileName,
    };

    ContentDispositionHeaderValue クラスのコンストラクタに inline を指定する。
    そうすることで応答ヘッダーに Content-Disposition: inline が設定され、ダウンロードしたファイルは保存ではなく直接ページに表示されるようになる。

    FileNameStar にはファイル名を指定する。
    自動でエンコードされるので、エンコード前の名前をそのまま指定して良い。

    Content-Disposition: inline の場合、ファイル名は指定しなくていいと思うのだが念のため設定している)

  4. 応答を返す

    メソッドの戻り値が IHttpActionResult なので、それに合うよう ResponseMessage() で変換した結果を返す。

    return ResponseMessage(res);

サンプルプログラム(HTML)

a タグでサクッと作れる。

href 属性には Web API の URL を設定する。
また target 属性には “_blank” を設定する。

これで新しいタブに Web API から返されたファイルが表示される。

<a href="~/api/files/download?fileName=%E3%83%86%E3%82%B9%E3%83%88.pdf" target="_blank">ダウンロード</a>

アカウントを作成 して、もっと沢山の記事を読みませんか?


この記事が気に入ったら ことりと さんを応援しませんか?
メッセージを添えてチップを送ることができます。


この記事にコメントをしてみませんか?


酒とアクアリウムが最近の楽しみ。

おすすめの記事