Resize and Upload Images with Blazor WebAssembly

This example uses ASP.NET 5 which requires .NET 5. It is incompatible with earlier versions of .NET including .NET Core 3.1.

This is an example of using the new InputFile of .NET 5.

This example involves turning the files into base64 strings to be uploaded via JSON to the server. It resizes images on the client-side, utilizing client resources thereby freeing server resources.

This example uploads image files, but it can be used to upload any kind of file. See this article for further examples.

Create a new .NET 5 (or later) Blazor WebAssembly project with an ASP.NET Core backend.

Add New File Class to Project

In the root of the shared project, create a file named ImageFile.cs.

// ImageFile.cs
public class ImageFile
{
	public string base64data { get; set; }
	public string contentType { get; set; }
	public string fileName { get; set; }
}

Create the Upload Controller

In the root of the server project, create a file named UploadController.cs.

// UploadController.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System;
using Microsoft.AspNetCore.Hosting;

namespace BlazorApp1.Server.Controllers
{
	[ApiController]
	[Route("api/[controller]")]
	public class UploadController : ControllerBase
	{
		private readonly IWebHostEnvironment env;

		public UploadController(IWebHostEnvironment env)
		{
			this.env = env;
		}

		[HttpPost]
		public async Task Post([FromBody] ImageFile[] files)
		{
			foreach (var file in files)
			{
				var buf = Convert.FromBase64String(file.base64data);
				await System.IO.File.WriteAllBytesAsync(env.ContentRootPath + System.IO.Path.DirectorySeparatorChar + Guid.NewGuid().ToString("N") + "-" + file.fileName, buf);
			}
		}
	}
}

Modify Index.razor

In the client project, modify Index.razor.

@page "/"
@inject HttpClient Http

<h1>@message</h1>

<div class="input-group">
	<div class="custom-file">
		<InputFile class="custom-file-input" multiple OnChange="OnChange" accept="image/png, image/jpeg, image/gif" id="inputFile" />
		<label class="custom-file-label" for="inputFile">Choose file</label>
	</div>
	<div class="input-group-append">
		<button class="btn btn-success" @onclick="Upload" disabled="@isDisabled">Upload</button>
	</div>
</div>

@foreach (var item in filesBase64)
{
	<img src="data:@item.contentType;base64,@item.base64data" />
}

@code {
	List<ImageFile> filesBase64 = new List<ImageFile>();
	string message = "InputFile";
	bool isDisabled = false;

	async Task OnChange(InputFileChangeEventArgs e)
	{
		var files = e.GetMultipleFiles(); // get the files selected by the users
		foreach(var file in files)
		{
			var resizedFile = await file.RequestImageFileAsync(file.ContentType, 640, 480); // resize the image file
			var buf = new byte[resizedFile.Size]; // allocate a buffer to fill with the file's data
			using (var stream = resizedFile.OpenReadStream())
			{
				await stream.ReadAsync(buf); // copy the stream to the buffer
			}
			filesBase64.Add(new ImageFile { base64data = Convert.ToBase64String(buf), contentType = file.ContentType, fileName = file.Name }); // convert to a base64 string!!
		}
		message = "Click UPLOAD to continue";
	}

	async Task Upload()
	{
		isDisabled = true;
		using (var msg = await Http.PostAsJsonAsync<List<ImageFile>>("/api/upload", filesBase64, System.Threading.CancellationToken.None))
		{
			isDisabled = false;
			if (msg.IsSuccessStatusCode)
			{
				message = $"{filesBase64.Count} files uploaded";
				filesBase64.Clear();
			}
		}
	}
}

Try the Home Page of The Project

Run the application to preview and then upload images to the server where they are saved in the server's content directory.

Coding Video

https://youtu.be/7oNhDxdZ3u8


Cookies are simple text files stored on the user's computer. They are used for adding features and security to this site.
OK