Blazor Server の<InputFile>組み込みコンポーネントを使った、ファイルアップロード処理を実装しました。<InputFile>のレイアウト、デザインを変更したパターン例も実装しています。
ソースコードはGitHubで公開しています。
ソースコード構成
Blazor Server テンプレートから、変更を加えたソースファイル。
ソースコード変更内容を解説
WebApplication1/_Imports.razor
・テスト画面で使用するコンポーネントの参照を追加。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@using System.Net.Http @using System.Web @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using WebApplication1 @using WebApplication1.Shared |
WebApplication1/Pages/InputFileTest.razor
・<InputFile>を使用したテスト画面を追加。
・3パターンの<InputFile>ボタンを設け、その下「読み込んだファイルの内容」欄に読み込んだファイルのファイル名、ファイルサイズ、ファイルの内容を表示している。
・Pattern 1 のボタンは<InputFile>をそのまま使った場合。
複数ファイルを1回で読み込める例としてmultipleを指定している。
・Pattern 2 のボタンは<InputFile>のデザインを<label>タグを使って変更した場合。
複数ファイルを1回で読み込める例としてmultipleを指定している。
・Pattern 3 のボタンは<InputFile>のデザインを<dev>タグを使って変更し、更に<InputFile>のパラメータ(InputFileChangeEventArgs)を明示的にメソッドパラメータとした渡した場合。
単一ファイルを1回で読み込む例としてmultipleを指定していない。
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
@page "/InputFileTest" <h1>InputFile Test</h1> <hr> <h3>Pattern 1</h3> <InputFile OnChange="@FileUpload1" multiple /> <hr> <h3>Pattern 2</h3> <label class="btn btn-primary" for="file_select2"> 複数ファイル読込み <InputFile id="file_select2" style="display:none;" OnChange="@FileUpload1" multiple /> </label>@fileName2 <hr> <h3>Pattern 3</h3> <div class="btn btn-primary file-input-button btn-one"> <InputFile OnChange="@(args => FileUpload2("テストパラメータ", args))" />単一ファイル読込み </div> <hr> <h4>読み込んだファイルの内容</h4> <div> @foreach (var result in resultList) { @result <br> } </div> @code { private string fileName2 = "ファイルは選択されていません。"; private string fileName3 = "ファイルは選択されていません。"; private List<string> resultList = new List<string>(); private List<IBrowserFile> loadedFiles = new List<IBrowserFile>(); private async Task FileUpload1(InputFileChangeEventArgs e) { loadedFiles.Clear(); foreach (var file in e.GetMultipleFiles()) { loadedFiles.Add(file); } resultList = new(); foreach (var file in loadedFiles) { resultList.Add(file.Name + " " + file.Size.ToString() + "byte"); var buffers = new byte[file.Size]; await file.OpenReadStream(file.Size).ReadAsync(buffers); resultList.Add(System.Text.Encoding.UTF8.GetString(buffers)); } } private async Task FileUpload2(string para, InputFileChangeEventArgs e) { loadedFiles.Clear(); foreach (var file in e.GetMultipleFiles()) { loadedFiles.Add(file); } resultList = new(); resultList.Add("メソッドパラメータ = " + para); foreach (var file in loadedFiles) { resultList.Add(file.Name + " " + file.Size.ToString() + "byte"); var buffers = new byte[file.Size]; await file.OpenReadStream(file.Size).ReadAsync(buffers); resultList.Add(System.Text.Encoding.UTF8.GetString(buffers)); } } } |
WebApplication1/wwwroot/css/site.css
・テスト画面の<InputFile>のデザイン変更に使用するCSSを追加。
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); html, body { font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; } a, .btn-link { color: #0366d6; } .btn-primary { color: #fff; background-color: #1b6ec2; border-color: #1861ac; } .content { padding-top: 1.1rem; } .valid.modified:not([type=checkbox]) { outline: 1px solid #26b050; } .invalid { outline: 1px solid red; } .validation-message { color: red; } #blazor-error-ui { background: lightyellow; bottom: 0; box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); display: none; left: 0; padding: 0.6rem 1.25rem 0.7rem 1.25rem; position: fixed; width: 100%; z-index: 1000; } #blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 0.75rem; top: 0.5rem; } .file-input-button { display: flex; align-items: center; justify-content: center; cursor: pointer; position: relative; } .file-input-button input[type=file] { position: absolute; width: 100%; height: 100%; opacity: 0; cursor: pointer; } .btn-one { background: #0070C0; width: 200px; } |
WebApplication1/Shared/NavMenu.razor
・作成したテスト画面へのリンクを、サイドメニューに追加。
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 34 35 36 37 38 39 40 41 42 43 44 |
<div class="top-row pl-4 navbar navbar-dark"> <a class="navbar-brand" href="">WebApplication1</a> <button class="navbar-toggler" @onclick="ToggleNavMenu"> <span class="navbar-toggler-icon"></span> </button> </div> <div class="@NavMenuCssClass" @onclick="ToggleNavMenu"> <ul class="nav flex-column"> <li class="nav-item px-3"> <NavLink class="nav-link" href="" Match="NavLinkMatch.All"> <span class="oi oi-home" aria-hidden="true"></span> Home </NavLink> </li> <li class="nav-item px-3"> <NavLink class="nav-link" href="counter"> <span class="oi oi-plus" aria-hidden="true"></span> Counter </NavLink> </li> <li class="nav-item px-3"> <NavLink class="nav-link" href="fetchdata"> <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data </NavLink> </li> <li class="nav-item px-3"> <NavLink class="nav-link" href="InputFileTest"> <span class="oi oi-list-rich" aria-hidden="true"></span> InputFile Test </NavLink> </li> </ul> </div> @code { private bool collapseNavMenu = true; private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; private void ToggleNavMenu() { collapseNavMenu = !collapseNavMenu; } } |
Visual Studio プロジェクト
今回使った Visual Studio プロジェクト テンプレートは、Blazor Server 5.0 の認証無し、HTTPS無しです。
コメント