130

Blazor WebAssembly File Upload Using MudBlazor UI Components

 2 years ago
source link: https://www.learmoreseekmore.com/2021/10/blazor-webassembly-fileupload-using-mudblazor-ui-components.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
In this article, we are going to implement a Blazor WebAssembly application file upload using MudBlazor UI components.

Create A Sample Blazor WebAssembly Application:

Let's create a sample Blazor WebAssembly application to accomplish our demo on file uploading.

Initial MudBlazor Setup:

Install the 'MudBlazor' library package.
Add Mudblazor namespace into the '_Imports.razor'.
_Imports.razor:
@using MudBlazor
Add the below CSS files inside of the head tag in 'index.html'.
wwwroot/index.html:
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
<link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />
Now comment the 'bootstrap.min.css' and '{your_applicationname}.styles.css' links in the head tag.
Add MudBlazor javascript file in 'index.html' just above the closing body tag.
wwwroot/index.html:
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
Register MudBlazor service in 'Program.cs'.
Program.cs:
  1. builder.Services.AddMudServices();
Now let's add some styling to 'MainLayout.razor' file with help MudBlazor components like 'MudThemeProvider', 'MudAppBar', 'MudText', etc.
Shared/MainLayout.razor:
  1. @inherits LayoutComponentBase
  2. <MudThemeProvider />
  3. <div class="page">
  4. <MudAppBar Color="Color.Info">
  5. <MudText Typo="Typo.h4">File Upload Demo</MudText>
  6. </MudAppBar>
  7. <div class="main mt-12" >
  8. <div class="content px-4">
  9. @Body
  10. </div>
  11. </div>
  12. </div>

Now our application looks as below.

MudBlazor To Compose File Upload:

Using HTML elements like 'label', 'input' we can create a file upload button.
The 'for' attribute value of the label must match with 'id' value of the 'input', we enable the 'input' to be triggered by clicking on the label. So the trick is to style the label to like like a button and hide the input.
Blazor WebAssembly from .Net 3.1 provides a default blazor component for file upload like 'InputFile'. So we can use 'InputFile' component instead of HTML 'input' filed.
We can make 'MudButton' component as a 'HTML' label element to do that 'MudButton' has an attribute like 'HtmlTag' and its value should be set like 'label'. By doing this HTML label getts rendered with all the beautiful styles of the MudBlazor button.

Implement File Upload Blazor Component Logic:

Let's first create the model class like 'SaveFile.cs' to capture the uploaded files.
Models/SaveFile.cs:
  1. using System.Collections.Generic;
  2. namespace Bwasm.MudFileUpload.UI.Models
  3. public class SaveFile
  4. public SaveFile()
  5. Files = new List<FileData>();
  6. public List<FileData> Files { get; set; }
  7. public class FileData
  8. public byte[] ImageBytes { get; set; }
  9. public string FileName { get; set; }
  10. public string FileType { get; set; }
  11. public long FileSize { get; set; }
Let's implement our logic in to the 'Index.razor' file. So let's update the 'Index.razor' as below.
Pages/Index.razor:(HTML Part)
  1. @page "/"
  2. <MudPaper Class="d-flex justify-center py-2 px-1 mt-6">
  3. <InputFile id="fileInput" OnChange="UploadFiles" hidden multiple />
  4. <MudButton HtmlTag="label"
  5. Variant="Variant.Filled"
  6. Color="Color.Success"
  7. StartIcon="@Icons.Filled.CloudUpload"
  8. for="fileInput">
  9. Upload Files
  10. </MudButton>
  11. </MudPaper>
  12. @if ((saveFile?.Files?.Count ?? 0) > 0)
  13. <MudPaper Class="d-flex justify-center py-2 px-1">
  14. @foreach (var item in saveFile?.Files)
  15. <MudPaper Class="pa-2 mx-2">
  16. <MudIconButton Color="Color.Error" Icon="@Icons.Material.Filled.Delete" OnClick="@(_ => RemoveImg(item))" aria-label="delete"></MudIconButton>
  17. <img width="150" height="150" src="@($"data:{item.FileType};base64,{Convert.ToBase64String(item.ImageBytes)}")">
  18. </MudPaper>
  19. </MudPaper>
  • (Line: 3-10) Using 'InputField' and 'MudButton' we are creating the file upload UI. Here on 'InputFile' component we added attributes like 'hidden'(to hide the HTML), 'multiple' (enables multiple images to upload). On 'MudButton' we must define the 'HtmlTag' and its value should be 'label'. On 'MudButton' component 'for' attribute value must be match with the 'id' value of the 'InputFile' component. The 'InputFile' component registered 'OnChange' event with 'UpLoadFiles' method.
  • (Line: 13-25) Preview section of the uploaded images.
  • (Line: 19) Delete button to remove the selected image. Button registered with a 'RemoveImg' method.
  • (Line: 21) Previewing the selected image.
Pages/Index.razor:(C# Part)
  1. @code{
  2. SaveFile saveFile = new SaveFile();
  3. private async Task UploadFiles(InputFileChangeEventArgs e)
  4. foreach (var file in e.GetMultipleFiles())
  5. var fileData = new FileData();
  6. var buffers = new byte[file.Size];
  7. await file.OpenReadStream().ReadAsync(buffers);
  8. fileData.FileName = file.Name;
  9. fileData.FileSize = file.Size;
  10. fileData.FileType = file.ContentType;
  11. fileData.ImageBytes = buffers;
  12. saveFile.Files.Add(fileData);
  13. private void RemoveImg(FileData file)
  14. saveFile.Files.Remove(file);
  • (Line: 2) Initialized the 'SaveFile' object to store the uploaded images.
  • (Line: 3-17) The 'UploadFiles' method registered with the 'OnChange' event of the 'InputFile' component.
  • (Line: 10) Fetching the image as bytes of data.
  • (Line: 19-22) Remove the selected image from the preview.

Now run the application and check the output.

Create API Endpoint To Save Files To Physical Location:

Create another sample .NetCore Web API application. Then we will create an endpoint to save the files to a physical location on the server. This endpoint will be consumed by our Blazor Assembly application.
Now create a payload object for our endpoint as below.
Models/SaveFile.cs:
  1. using System.Collections.Generic;
  2. namespace Bwasm.MudFileUpload.API.Models
  3. public class SaveFile
  4. public SaveFile()
  5. Files = new List<FileData>();
  6. public List<FileData> Files { get; set; }
  7. public class FileData
  8. public byte[] ImageBytes { get; set; }
  9. public string FileName { get; set; }
  10. public string FileType { get; set; }
  11. public long FileSize { get; set; }
Now write an endpoint that has an implementation of saving the file to the physical folder location.
Controllers/FileUpLoadController.cs:
  1. using Bwasm.MudFileUpload.API.Models;
  2. using Microsoft.AspNetCore.Mvc;
  3. using System;
  4. using System.Threading.Tasks;
  5. namespace Bwasm.MudFileUpload.API.Controllers
  6. [Route("api/[controller]")]
  7. [ApiController]
  8. public class FileUploadController : ControllerBase
  9. [HttpPost]
  10. [Route("save-file-to-physicallocation")]
  11. public async Task<IActionResult> SaveToPhysicalLocation([FromBody] SaveFile saveFile)
  12. foreach (var file in saveFile.Files)
  13. string fileExtenstion = file.FileType.ToLower().Contains("png") ? "png" : "jpg";
  14. string fileName = $@"D:\MyTest\{Guid.NewGuid()}.{fileExtenstion}";
  15. using (var fileStream = System.IO.File.Create(fileName))
  16. await fileStream.WriteAsync(file.ImageBytes);
  17. return Ok();
  • (Line: 16) Looping the collection of file information.
  • (Line: 19) The full path of the file name. It is always recommended to save the files in non-application folder on the server.
  • (Line: 20) The 'System.IO.File.Create("image_path")' generates the file stream at the specified path.
  • (Line: 22) Saving the files array of byte data to the specified physical path.
To consume this endpoint by our Blazor Application enable cors.
Startup.cs:
  1. public void ConfigureServices(IServiceCollection services)
  2. services.AddCors(options =>
  3. options.AddPolicy(name: "MyAllowSpecificOrigins",
  4. builder =>
  5. builder.AllowAnyOrigin();
  6. builder.AllowAnyHeader();
  7. builder.AllowAnyMethod();
  8. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  9. app.UseCors("MyAllowSpecificOrigins");

Invoke API Endpoint From Blazor WebAssembly Application:

Add our web API domain to HttpClient configuration in Program.cs file.
Program.cs:
  1. builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("https://localhost:6001/") });
Now lets add new button to upload the images to server.
Pages/Index.razor:(Html Part)
  1. @page "/"
  2. @inject HttpClient Http
  3. <MudPaper Class="d-flex justify-center py-2 px-1 mt-6">
  4. <InputFile id="fileInput" OnChange="UploadFiles" hidden multiple />
  5. <MudButton HtmlTag="label"
  6. Variant="Variant.Filled"
  7. Color="Color.Success"
  8. StartIcon="@Icons.Filled.CloudUpload"
  9. for="fileInput">
  10. Upload Files
  11. </MudButton>
  12. <MudButton OnClick="SaveToServer"
  13. Variant="Variant.Filled"
  14. Color="Color.Warning"
  15. StartIcon="@Icons.Filled.CloudUpload"
  16. for="fileInput">
  17. Upload Files To Server
  18. </MudButton>
  19. </MudPaper>
  • (Line: 2) Inject the 'HttpClient'.
  • (Line: 13-19) Add new button that will invoke the API call for uploading the image to the server. Here click event registered with 'SaveToServer' method.
Pages/Index.razor:(C# Part)
  1. private async Task SaveToServer()
  2. await Http.PostAsJsonAsync("/api/FileUpload/save-file-to-physicallocation", saveFile);

Support Me!
Buy Me A Coffee PayPal Me

Video Session:

Wrapping Up:

Hopefully, I think this article delivered some useful information on the Blazor WebAssembly File Upload using MudBalzor UI Components. I love to have your feedback, suggestions, and better techniques in the comment section below.

Follow Me:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK