情報応用演習Ⅰ(2024)

【T10b】簡易ブログソフトウェアの作成 Part.Ⅳ ~ ファイルのアップロード/ダウンロード(5/7)

プロジェクトタイプ(注意: 本文参照)
プロジェクト名T10b
ソリューション名PIT10
注意
  • 本ページの作業内容は 前のページまでの続き になっていることに注意せよ.
    • 先に前のページまでをすべて読み,指示されている作業を済ませてから本ページを読むこと.
    • プロジェクトの作成作業については準備作業を参照せよ.

10b-5. GetAttachmentアクションとビューの作成

ここまでで,ファイルをアップロードする機能は実装できた.しかし現状ではアプリを動作させているコンピューターに, ファイルが保存されるばかりで,アプリの利用者がそのファイルを表示 or ダウンロードすることができない. そのため,次は添付ファイルの取得(≒ダウンロード)のためのアクションを作成しよう. Articlesコントローラーに_に示す内容を追記しよう.

Articlesコントローラーの追記内容(GetAttachment)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// GetAttachmentアクション(GETのみ)
public async Task<IActionResult> GetAttachment(int? id) 
{
    if (id == null)                                                 // ルーティングパラメーターが
    {                                                               // 指定されていなければ
        return NotFound();                                          // 404 Not Found を返す.
    }                                                               //

    var attachment = await _context.Attachments                     // 指定されたIDから,
        .Include(a => a.Article)                                    // 表示対象の添付ファイルを
        .FirstOrDefaultAsync(m => m.AttachmentId == id);            // 検索する.

    if (attachment == null)                                         // 指定されたファイルが
    {                                                               // 見つからなければ
        return NotFound();                                          // 404 Not Found を返す.
    }                                                               //

    BlogUser? currentUser = await _userManager.GetUserAsync(User);  // ログイン中のユーザー情報を取得して
    if (!await IsReadableAsync(currentUser, attachment.Article!))   // 閲覧可能かどうかを調べる.
    {                                                               //
        return Forbid();                                            // 閲覧不可の場合は 403 Forbidden を返す.
    }                                                               //

    var filepath = GetAttachmentFilePath(attachment);               // 添付ファイルを保存するパスを取得する

    if (!System.IO.File.Exists(filepath))                           // 何らかの理由で保存フォルダ内に
    {                                                               // 添付ファイルが見つからなければ
        return NotFound();                                          //  404 Not Found を返す.
    }                                                               //

    var strm = System.IO.File.OpenRead(filepath);                   // ファイルを開いて,
    return File(strm, attachment.ContentType, attachment.Filename); // ファイルそのものをレスポンスとして返す.
}

18~22行目では,リスト9b-3-6で定義したIsReadableAsync()メソッドを使用して その添付ファイルに関連付けられた記事が,アクセス中のユーザーにとって閲覧可能であるかを判定している. つまり,その記事がアクセス中のユーザーにとって閲覧不可なのであれば,それに関連付けられた添付ファイルも閲覧不可と判定する.

31~32行目では,File()メソッドを 使用して,ファイルシステムに保存された添付ファイルを開いて,ファイルそのものをレスポンスとしてクライアントに返却している. このため,このアクションはビューを必要としない.

ここまで書けたら実行してみよう.記事の一覧の中から, 先ほどファイルを添付した記事 の タイトルをクリックして記事の個別表示画面(Details)を表示させよう(__). 一覧から先ほど添付したファイルをクリックするとそのファイルがダウンロードされるはずである(__).

実行結果
Last updated on 2024-06-18
Published on 2024-06-18

Powered by Hugo. Theme by TechDoc. Designed by Thingsym.