Implement File Upload in a Blazor Web Assembly Application using .Net 7

Introduction

The previous article discussed performing the CRUD-based operation in a Blazor Web Assembly-based application. In that article, we generate a complete UI-based component related to Employees. In that demo, we have seen how to populate the list of employees and create new Employees and other operations. This article will discuss the file uploader functionality in the Blazor Web Assembly. We will upload the employee profile picture-related file and then demonstrate those details in the Employee List and other related segments.

Blazor FileUpload banner

If you want to read the previous article related to the CRUD operation in Blazor Web Assembly, use the below links: CRUD Operations with EF Core 7 in Blazor WebAssembly (c-sharpcorner.com)

Github Repo Links for the entire code sample:- debasis-saha/blazor_wasm_employee_crud_ops (github.com)

Create a Database Structure to store Employee Profile Picture information

Before coding into the Blazor Application, we must implement the Database structure changes related to the employee profile pictures. So, related that create the below table in the database.

CREATE TABLE [dbo].[EmployeeProfilePics]
(
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[EmployeeId] [int] NULL,
	[ImageType] [varchar](50) NULL,
	[Thumbnail] [text] NOT NULL,
	[ImageUrl] [varchar](200) NOT NULL,
	CONSTRAINT [PK_EmployeeProfilePics] PRIMARY KEY CLUSTERED ([Id] ASC) ON [PRIMARY],
	CONSTRAINT [FK_EmployeeProfilePics_Employees] FOREIGN KEY([EmployeeId]) REFERENCES [dbo].[Employees] ([Id])
)
GO

Add Employee Profile Image into the Employee Add/Update Operation

We have already created the Database structure to capture the Employee Profile Information. Now, we first need to make the related model class. So, Add a new class file called EmployeeProfilePic within the Model folder and add the below code into that file.

public class EmployeeProfilePic
{
    public int Id { get; set; }

    [ForeignKey("EmployeeId")]
    [Required]
    public int EmployeeId { get; set; }

    public string ImageType { get; set; }

    public string? Thumbnail { get; set; }

    public string? ImageUrl { get; set; }

    public virtual Employee? EmployeeInfo { get; set; }
}

Now, open the Employee.cs model class from the Model folder and add the below properties at the end related to capturing the profile file information.

[NotMapped]
public int? EmployeeProfilePicId { get;set; }

[NotMapped]
public string? thumbnail { get; set; }

[NotMapped]
public string? ImageType { get; set; }

Now, open the EmployeeInfo.razor component file. In that file, after the Phone, no Section, add the below file uploader-related code.

<div class="row mb-3">
     <label for="inputPhone" class="col-sm-2 col-form-label">Profile Image</label>
     <div class="col-sm-10">
         <InputFile class="form-control" id="empphone" hidden=@ReadOnlyMode OnChange="@OnInputFileChange" />
         <div>
             <img src="@Employee.thumbnail" height="200px" width="200px">
         </div>
     </div>
 </div>

Now, in the same EmployeeInfo.razor file, add the below code into the @code section related to reading the uploaded file, and convert the file information to base64 format.

private async Task OnInputFileChange(InputFileChangeEventArgs e)
{
    IBrowserFile imgFile = e.File;
    var buffers = new byte[imgFile.Size];
    await imgFile.OpenReadStream().ReadAsync(buffers);
    string imageType = imgFile.ContentType;
    string fileName = imgFile.Name;
    Employee.thumbnail = $"data:{imageType};base64,{Convert.ToBase64String(buffers)}";
    Employee.ImageType = imageType;
}

Now, open the EmployeeController.cs File and relace the SaveEmployee() related code with the below one.

[Route("SaveEmployee")]
[HttpPost]
public async Task<IActionResult> SaveEmployee(Employee employee)
{
    try
    {
        if (_dbContext.Employees == null)
        {
            return Problem("Entity set 'AppDbContext.Employee'  is null.");
        }

        if (employee != null)
        {
            _dbContext.Add(employee);
            await _dbContext.SaveChangesAsync();

            if (!string.IsNullOrEmpty(employee.thumbnail) && employee.Id>0)
            {
                EmployeeProfilePic employeeProfilePic = new EmployeeProfilePic();
                employeeProfilePic.Id = Employee.EmployeeProfilePicId > 0 ? (int) Employee.EmployeeProfilePicId : 0;
                employeeProfilePic.ImageType = Employee.ImageType;
                employeeProfilePic.Thumbnail = employee.thumbnail;
                employeeProfilePic.EmployeeId = employee.Id;
                employeeProfilePic.ImageUrl = "localhost";

                _dbContext.Add(employeeProfilePic);
                await _dbContext.SaveChangesAsync();
            }                                                               

            return Ok("Save Successfully!!");
        }
    }
    catch (Exception ex)
    {
        throw (ex);
    }

    return NoContent();
}

Now, run the application and create a new Employee with a profile picture.

Employee Details

Retrieve Employee Profile Picture to display in Employee List

As we save the employee profile picture already. We need to display that profile picture on the employee list. First, we must make the code changes below in the GetEmployees() method.

[Route("GetEmployees")]
[HttpGet]
public async Task<IList<Employee>> GetEmployees()
{
    try
    {
        var _data = await (from emp in _dbContext.Employees
                           join pic in this._dbContext.EmployeeProfilePics on emp. Id equals pic.EmployeeId into p
                           from pic in p.DefaultIfEmpty()
                           select new Employee
                           {
                               Id = emp.Id,
                               Code = emp.Code,
                               FullName = emp.FullName,
                               DOB = emp.DOB,
                               Address = emp.Address,
                               City = emp.City,
                               PostalCode = emp.PostalCode,
                               State = emp.State,
                               Country = emp.Country,
                               EmailId = emp.EmailId,
                               PhoneNo = emp.PhoneNo,
                               JoiningDate = emp.JoiningDate,
                               ImageType = pic.ImageType,
                               thumbnail = pic.Thumbnail,
                               EmployeeProfilePicId = pic.Id
                           }).ToListAsync();
        return _data;
    }
    catch (Exception ex)
    {
        throw (ex);
    }
}

Now, also, make the below code changes for the retrieve employee information by the Id method – 

[Route("GetEmployee/{id}")]
[HttpGet]
public async Task<Employee> GetEmployee(int id)
{
    try
    {
        var _data = await (from emp in _dbContext.Employees
                           join pic in this._dbContext.EmployeeProfilePics on emp.Id equals pic.EmployeeId into p
                           from pic in p.DefaultIfEmpty()
                           where (emp.Id.Equals(id))
                           select new Employee
                           {
                               Id = emp.Id,
                               Code = emp.Code,
                               FullName = emp.FullName,
                               DOB = emp.DOB,
                               Address = emp.Address,
                               City = emp.City,
                               PostalCode = emp.PostalCode,
                               State = emp.State,
                               Country = emp.Country,
                               EmailId = emp.EmailId,
                               PhoneNo = emp.PhoneNo,
                               JoiningDate = emp.JoiningDate,
                               ImageType = pic.ImageType,
                               thumbnail = pic.Thumbnail,
                               EmployeeProfilePicId = pic.Id
                           }).FirstOrDefaultAsync();


        return _data;
    }
    catch (Exception ex)
    {
        throw (ex);
    }
}

Now, open the EmployeeList.razor view component and add the below code in the HTML section to display the profile image – 

@foreach (var employee in employees)
{
    <tr>
        <td width="25%">
            <img src="@employee.thumbnail" alt="" width="32" height="32" class="rounded-circle me-2">
            <a href="@GetEmployeeViewUrl(@employee)">@employee.FullName</a>
        </td>
        <td width="10%">@employee.Code</td>
        <td width="10%">@employee.DOB.ToShortDateString()</td>
        <td width="15%">@employee.State</td>
        <td width="15%">@employee.City</td>
        <td width="10%">@employee.JoiningDate.ToShortDateString()</td>
        <td width="7%">
            <a href="@GetEditEmployeeViewUrl(@employee)" class="btn btn-primary" tabindex="-1" role="button" aria-disabled="true">
                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil-fill" viewBox="0 0 16 16">
                    <path d="M12.854.146a.5.5 0 0 0-.707 0L10.5 1.793 14.207 5.5l1.647-1.646a.5.5 0 0 0 0-.708l-3-3zm.646 6.061L9.793 2.5 3.293 9H3.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.207l6.5-6.5zm-7.468 7.468A.5.5 0 0 1 6 13.5V13h-.5a.5.5 0 0 1-.5-.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.5-.5V10h-.5a.499.499 0 0 1-.175-.032l-.179.178a.5.5 0 0 0-.11.168l-2 5a.5.5 0 0 0 .65.65l5-2a.5.5 0 0 0 .168-.11l.178-.178z"></path>
                </svg> Edit
            </a>
        </td>
        <td width="8%">
            <a class="btn btn-danger" tabindex="-1" role="button" aria-disabled="true" @onclick="_ => DeleteEmployee(employee)">
                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil-fill" viewBox="0 0 16 16">
                    <path d="M12.854.146a.5.5 0 0 0-.707 0L10.5 1.793 14.207 5.5l1.647-1.646a.5.5 0 0 0 0-.708l-3-3zm.646 6.061L9.793 2.5 3.293 9H3.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.207l6.5-6.5zm-7.468 7.468A.5.5 0 0 1 6 13.5V13h-.5a.5.5 0 0 1-.5-.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.5-.5V10h-.5a.499.499 0 0 1-.175-.032l-.179.178a.5.5 0 0 0-.11.168l-2 5a.5.5 0 0 0 .65.65l5-2a.5.5 0 0 0 .168-.11l.178-.178z"></path>
                </svg> Delete
            </a>
        </td>
    </tr>
}

Now, run the application to check the employee list data.

Employee Details

Now, click on the Employee Name link to display the employee information in the details view.

Employee View

Conclusion

So, in this article, we discuss how to upload a profile image for any employee with the help of CRUD operation within a Blazor Web Assembly. Any queries, suggestions, or feedback about this article are always welcome.


Similar Articles