
【Blazor】 InputFileを使ったBlazorファイルアップロード&ダウンロード
- ファイルのアップロード
- ファイルのダウンロード
- まとめ
目次
ファイルのアップロード

.NET5以降では、InputFileコンポーネントを使って、ファイルを読み込むことができます。 今回は、外部からファイルを読み込み後、wwwroot/uploadへファイルをアップロードするサンプルになります。
以下サンプルコードになります。
@page "/upload" @using Microsoft.AspNetCore.Components.Forms @inject IWebHostEnvironment WebHostEnvironment <h3>アップロード検証</h3> <hr /> <p><var>wwwroot/upload</var>をアップロード</p> <InputFile OnChange="ChangeFileAsync" /> @if (!string.IsNullOrEmpty(Message)) { <p>@Message</p> } @code { /// <summary> /// メッセージ /// </summary> private string Message = string.Empty; /// <summary> /// ファイルサイズの上限値(今回は 10MB に設定) /// </summary> private long maxFileSize = 10485760; /// <summary> /// ファイル変更時の処理 /// </summary> /// <param name="e">イベント引数</param> private async Task ChangeFileAsync(InputFileChangeEventArgs e) { IBrowserFile file = e.File; if (file.Size > maxFileSize) { Message = $"ファイルサイズが大きすぎます。最大 {maxFileSize / (1024 * 1024)} MB までアップロード可能です。"; return; } var uploadPath = Path.Combine(WebHostEnvironment.WebRootPath, "upload"); Directory.CreateDirectory(uploadPath); var filePath = Path.Combine(uploadPath, file.Name); // ファイルサイズ制限(maxFileSize)を設定 using var fileStream = file.OpenReadStream(maxFileSize); using var memoryStream = new MemoryStream(); await fileStream.CopyToAsync(memoryStream); await File.WriteAllBytesAsync(filePath, memoryStream.ToArray()); Message = $"{file.Name}がアップロードされました。"; } }
InputFileコンポーネントでは、OnChangeにファイル選択時の処理を登録することができます。 登録できるのは、InputFileChangeEventArgsを引数にもつメソッドChangeFileAsyncになります。
ChangeFileAsyncメソッドでは、イベント引数からIBrowserFileを取得しています。 IBrowserFileインターフェースを通じて、ファイル名やファイルサイズ等の情報を取得したり、 ファイルを読み取るためのストリームを開くOpenReadStreamを呼び出すことができます。
OpenReadStreamでは、引数にファイルサイズの最大許容サイズ(バイト単位)を指定することができます。 指定しない場合は、512KBまでに制限されます。 今回は、10MBを許容値とするため、それをバイトへ変換した10485760を指定しています。 アップロードするデータに応じて、調整してみてください。 ちなみに、許容値は超えた場合は、以下のようなエラーになります。
【以下のようなエラーになる】 Error: System.IO.IOException: Supplied file with size 660890 bytes exceeds the maximum of 512000 bytes.
最後に、OpenReadStreamで読み取ったファイルデータを、memoryStreamを使ってメモリ内に一時的にコピーし、 ファイルのアップロード先であるfilePathに書き込んでいます。
動作確認をしてみると、ファイル選択後にwwwroot/uploadにデータがアップロードされていることが確認できます。


ファイルのダウンロード

[wwwroot/download/Test.pdf]をダウンロードするサンプルを見ていきます。 ファイルのダウンロードは、JavaScriptを介して実行する必要があります。
まずダウンロードを行うJavaScriptのソースを見ていきます。
// ファイルダウンロード function downloadFile(data) { // Blob作成 const blob = new Blob([data.byteArray], { type: data.contentType }); // ダウンロード可能なリンクを作成 const url = URL.createObjectURL(blob); // URL からのダウンロードを開始する const anchorElement = document.createElement('a'); anchorElement.href = url; anchorElement.download = data.fileName ?? ''; anchorElement.click(); anchorElement.remove(); // URLの後始末 URL.revokeObjectURL(url); }
このdownloadFileメソッドでは、Blobを作成して、ダウンロード可能なURLを作成しています。 そのURLから<a>タグを作成して、クリック処理を行うことによってダウンロードを実現しています。
Blobについて知りたい方は、以下の記事を参考にしてみてください。
【Blobとは何か理解していない方へ】 https://zenn.dev/kazu1/articles/736991963449d6
次にjavascriptの参照を追加します。
@using Microsoft.AspNetCore.Components.Web @namespace Blazor_UploadAndDownload.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <base href="~/" /> <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" /> <link href="css/site.css" rel="stylesheet" /> <link href="Blazor_UploadAndDownload.styles.css" rel="stylesheet" /> <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" /> </head> <body> @RenderBody() <div id="blazor-error-ui"> <environment include="Staging,Production"> An error has occurred. This application may no longer respond until reloaded. </environment> <environment include="Development"> An unhandled exception has occurred. See browser dev tools for details. </environment> <a href="" class="reload">Reload</a> <a class="dismiss">🗙</a> </div> <script src="_framework/blazor.server.js"></script> @* ↓↓↓ ここに追記必要 ↓↓↓ *@ <script src="js/functions.js"></script> </body> </html>
33行目のようにjavascript参照するコードを追加してください。
最後にダウンロードページを作成します。以下サンプルコードになります。
@page "/download" @inject IJSRuntime JSRuntime @inject IWebHostEnvironment WebHostEnvironment <h3>ダウンロード検証</h3> <hr /> <p>[wwwroot/download/Test.pdf]をダウンロード</p> <button @onclick="DownloadFileAsync">ダウンロード</button> @code { private async Task DownloadFileAsync() { // ファイルのバイナリデータを取得 var filePath = Path.Combine(WebHostEnvironment.WebRootPath, "download", "Test.Pdf"); var fileBytes = await File.ReadAllBytesAsync(filePath); var fileName = "Test.Pdf"; var contentType = "application/pdf"; // JavaScriptの関数(downloadFromByteArray)を呼び出して、ダウンロードを開始する await JSRuntime.InvokeVoidAsync( "downloadFile", new { byteArray = fileBytes, contentType = contentType, fileName = fileName }); } }
javascriptのメソッドdownloadFileメソッドをIJSRuntimeを介して呼び出しています。 引数には、ファイルのバイナリデータbyteArrayやMIMEタイプcontentType、ファイル名fileNameを渡しています。
動作確認してみると、 [wwwroot/download/Test.pdf]からPDFをダウンロードすることが確認できます。

まとめ

今回は、ファイルのアップロードとダウンロードする方法について解説しました。 CSVファイルのアップロードやレポートのダウンロードはよく使う機能だと思いますので、是非活用してみてください。
この本では、Blazorの基本から高度なテクニックまで、実際のプロジェクトに役立つ知識を網羅しています。 初心者から経験者まで、Blazorを扱うすべての開発者にとっての必読書です。 この記事の執筆者も参考にした「Blazor入門」で、あなたのBlazorスキルを飛躍的に向上させませんか?
合わせて読みたい

コンポーネントにのみCSSを適用する方法
Blazorで特定のコンポーネントに限定したCSSを適用する方法を紹介。.NET5から導入されたCSS分離を活用し、他のコンポーネントやライブラリとのCSS競合を回避。コンポーネント[CssIsolationComponent.razor]とそのCSS[CssIsolationComponent.razor.css]を作成。この技術により、[CssIsolationComponent.razor]のpタグ部分の背景だけが赤くなることを示す。効率的なデザイン管理のためにCSS分離の使用を推奨。
更新日:2023/07/26

Virtualizeコンポーネントの使い方
Blazorの仮想化コンポーネントを活用し、大量のデータを効率的に表示する方法を解説。画面内の要素のみをレンダリングし、スクロール時にデータを動的に読み込む手法や注意点を説明。
更新日:2023/07/26