テキストデータのファイルダウンロード、画像データのファイルダウンロード 処理。
ソースコードはGitHubで公開しています。
ソースコード構成
ソースコード変更内容を解説
WebApplication1.csprojDownload/Question.jpg
・ダウンロード対象ファイルとして Question.jpg を追加。
wwwroot/js/common.js
・ファイルダウンロード処理用の JavaScript を追加。
1 2 3 4 5 6 7 8 9 10 |
function saveAsFile(filename, bytesBase64) { var link = document.createElement('a'); link.download = filename; link.href = "data:application/octet-stream;base64," + bytesBase64; document.body.appendChild(link); link.click(); document.body.removeChild(link); } |
Pages/_Host.cshtml
・JavaScriptファイルの参照を追加。
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 |
@page "/" @namespace WebApplication1.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @{ Layout = null; } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>WebApplication1</title> <base href="~/" /> <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" /> <link href="css/site.css" rel="stylesheet" /> <link href="WebApplication1.styles.css" rel="stylesheet" /> </head> <body> <component type="typeof(App)" render-mode="ServerPrerendered" /> <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/common.js"></script> </body> </html> |
SharedData/FolderPath.cs
・WEBアプリ全体で再利用する static データ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
namespace WebApplication1.SharedData { /// <summary> /// アプリケーション全体で共有するパス情報などを纏めるクラス /// </summary> public static class FolderPath { /// <summary> /// ダウンロードファイル置き場 /// </summary> public static string Download; } } |
Startup.cs
・WEBアプリ起動時に、FolderPath.Download に値を設定する。
・RuntimeInformation.IsOSPlatform() で、実行環境がWindows場合、Linuxの場合とで、パスを切り替えている。
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 |
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using WebApplication1.Data; using WebApplication1.SharedData; namespace WebApplication1 { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); services.AddServerSideBlazor(); services.AddSingleton<WeatherForecastService>(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // on Windows FolderPath.Download = env.WebRootPath + "\\..\\Download"; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { // on Linux FolderPath.Download = env.WebRootPath + "/../Download"; } else { throw new NotImplementedException(); } if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); } app.UseStaticFiles(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); }); } } } |
_Imports.razor
・参照先を追加。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@using System.Net.Http @using System.IO @using System.Text @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 @using WebApplication1.SharedData |
Shared/NavMenu.razor
・Download File 画面へのリンクを追加。
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="DownloadFile"> <span class="oi oi-plus" aria-hidden="true"></span> Download File </NavLink> </li> </ul> </div> @code { private bool collapseNavMenu = true; private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; private void ToggleNavMenu() { collapseNavMenu = !collapseNavMenu; } } |
Pages/DownloadFile.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 |
@page "/DownloadFile" @inject IJSRuntime JS <h1>Download File</h1> <button class="btn btn-primary" @onclick="DownloadFileExec_Text">Text file download</button> <button class="btn btn-primary" @onclick="DownloadFileExec_Image">Image file download</button> @code { private async Task DownloadFileExec_Text() { var filename = "ビジネスデータ.txt"; //ビジネスロジックで生成したデータ(仮) var textData = "1234567890 abcd あいうえお"; var byteData = Encoding.UTF8.GetBytes(textData); await JS.InvokeVoidAsync("saveAsFile", filename, Convert.ToBase64String(byteData)); } private async Task DownloadFileExec_Image() { var filename = "Question.jpg"; var path = Path.Combine(FolderPath.Download, filename); var data = File.ReadAllBytes(path); await JS.InvokeVoidAsync("saveAsFile", filename, Convert.ToBase64String(data)); } } |
Visual Studio プロジェクト
今回使った Visual Studio プロジェクト テンプレートは、Blazor Server 5.0 の認証無し、HTTPS無しです。
コメント