In this article, we are going to do a demo on file downloading in the blazor webassembly application.
Now register the 'AddHttpClient' in the 'Program.cs'.
Create A .Net6 Blazor WebAssembly Application:
Let's create a .Net6 Blazor WebAssembly sample application to accomplish our demo. We can use either Visual Studio 2022 or Visual Studio Code(using .NET CLI commands) to create any.Net6 application. For this demo, I'm using the 'Visual Studio Code'(using the .NET CLI command) editor.
CLI command
dotnet new blazorwasm -o Your_Project_Name
dotnet new blazorwasm -o Your_Project_Name
Install And Configure HttpClient Instance:
Install the 'Microsoft.Extensions.Http' NuGet.
Package Manager
Install-Package Microsoft.Extensions.Http -Version 6.0.0
Install-Package Microsoft.Extensions.Http -Version 6.0.0
CLI command
dotnet add package Microsoft.Extensions.Http --version 6.0.0
dotnet add package Microsoft.Extensions.Http --version 6.0.0
Now register the 'AddHttpClient' in the 'Program.cs'.
Program.cs:
builder.Services.AddHttpClient();
Implement File Downloading Logic:
Let's implement our sample in the 'Index.razor' page component. First, let's create a Model like 'Models/FileCotainer.cs'.
Models/FileContainer.cs:
namespace Dot6.Bwasm.FileDownload.Learn.Models; public class FileContainer { public string ImageUrl { get; set; } public string FileName { get; set; } }Index.razor:(HTML Part)
@page "/" @inject IHttpClientFactory _httpClientFicatory; @inject IJSRuntime JS <div class="container"> <div class="row"> <div class="col col-md-4 offset-md-4"> <div class="card" style="width: 18rem;"> <img src="@fileContainer.ImageUrl" class="card-img-top" alt="..."> <div class="card-body text-center"> <button class="btn btn-primary" type="button" @onclick="@(() => DownLoadImage(fileContainer.ImageUrl,fileContainer.FileName))">Download File</button> </div> </div> </div> </div> </div>
- (Line: 2)Inject the 'IHttpClientFactory'.
- (Line: 3) Inject the the 'IJSRuntime' that helps to interact with javascript from our blazor component.
- (Line: 9) Image URL binded.
- (Line: 11-13)Button click event registered with 'DownLoadImage()' image method. To this 'DonLoadImage()' method image URL and image name are passed as input parameter.
@code { private FileContainer fileContainer = new FileContainer() { FileName = "Ironman.jpg", ImageUrl = "https://st1.bollywoodlife.com/wp-content/uploads/2019/01/Iron-Man-1.jpg?impolicy=Medium_Widthonly&w=600" }; private async Task DownLoadImage(string imgUrl, string fileName) { var request = new HttpRequestMessage(HttpMethod.Get, imgUrl ); var httpClient = _httpClientFicatory.CreateClient(); var response = await httpClient.SendAsync(request); var imgStream = await response.Content.ReadAsStreamAsync(); using var streamRef = new DotNetStreamReference(stream: imgStream); await JS.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef); } }
- (Line: 3-7) Initialized the 'FileContainer' with same test data like 'Image URL', 'Image Name'.
- (Line: 8-17) The 'DownLoadImage()' method that gets invoked on click the 'File DownLoad' button.
- (Line: 10-11) Initialized the 'HttpRequestMessage' to which will pass the download URL as an input parameter.
- (Line: 12) Creating the HttpClient instance form the 'IHttpClientFactory'.
- (Line: 13) Using the 'httpClient.SendAsync()' method calls the image URL.
- (Line: 14) Reading the image URL response as a stream of data.
- (Line: 15) Initialized the 'DotNetStreamReference()' by passing the response stream as input parameter.
- The 'DoNetStreamReference' is to create a reference to a .Net stream sent to javascript.
- (Line: 16) Invoking the javascript method 'downloadFileFromStream'(we will implement this in javascript in the next step) and passing the file name and file stream to it.
wwwroot/js/app.js:
async function downloadFileFromStream(fileName, contentStreamReference) { const arrayBuffer = await contentStreamReference.arrayBuffer(); const blob = new Blob([arrayBuffer]); const url = URL.createObjectURL(blob); triggerFileDownload(fileName, url); URL.revokeObjectURL(url); } function triggerFileDownload(fileName, url) { const anchorElement = document.createElement("a"); anchorElement.href = url; if (fileName) { anchorElement.download = fileName; } anchorElement.click(); anchorElement.remove(); }
- (Line: 1-10) The 'downloadFileFromStream()' method takes 'file name', 'file stream reference' as input parameters.
- (Line: 2) Reading the files stream reference as the buffer.
- (Line: 3) Initialized the 'Blob' that helps to read the file data.
- (Line: 5) Creating the file URL with the help of 'URL.createObjectURL()'.
- (Line: 12-22) The 'triggerFileDownload()' method contains logic to create a dynamic anchor tag and to that anchor tag our file stream URL passed as src value and then calls the anchor tag download and then calls click event of anchor tag to download file and then remove the dynamically created anchor tag.
- (Line: 9) After file download relieve the URL resources by calling the 'revokeObjectURL()' method.
Support Me!
Buy Me A Coffee
PayPal Me
Video Session:
Wrapping Up:
Hopefully, I think this article delivered some useful information on file downloading in the Blazor WebAssembly application. using I love to have your feedback, suggestions, and better techniques in the comment section below.
It should be forewarned that this technique, specifically the JavaScript code that does `const blob = new Blob([arrayBuffer]);` effectively creates an in-memory array. Therefore, it is not possible to use this code for download large, dynamic content, say 2 GB or more, and attempt to save it as a file.
ReplyDelete