Upload And Display Image In ASP.NET Core 3.1

In this article, I will explain how to upload and display images. This article will help you to understand image tag helper and IFormFile in asp.net core. Image Tag Helper enhances the img tag to provide cache busting behavior for static image files. A unique cache-busting string is appended as a query parameter to the image source. The file on the host web server changes, and a unique request URL is generated that includes the updated request parameter. IFormFile which is a C# representation of the file is used to process or save the file.

Here is the complete code.

This is how we display images in asp.net core.

<img src="~/images/@employee.ProfilePicture" class="rounded-circle" height="40" width="40" asp-append-version="true" />

Step 1. Start up Visual Studio 2019. Now click on Create New Project Choose ASP.NET Core Web Application and click on “Next”.

After clicking next, another wizard will open. Under the project name, give a meaningful name to your project and click on create.

That will open up another new wizard. Select ASP.Net Core 3.0 from the dropdown. If not, select default. Choose the Web Application (Model-View-Controller) template and click on Create which will create ASP.Net Core Application.

Step 2. Now right-click on the Models folder and “Add” class and name it Employee.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace MvcCoreUploadAndDisplayImage_Demo.Models
{
    public class Employee
    {
        [Key]
        public int Id { get; set; }
        [Required(ErrorMessage = "Please enter first name")]
        [Display(Name = "First Name")]
        [StringLength(100)]
        public string FirstName { get; set; }
        [Required(ErrorMessage = "Please enter last name")]
        [Display(Name = "Last Name")]
        [StringLength(100)]
        public string LastName { get; set; }
        [Display(Name = "Full Name")]
        public string FullName { get; set; }
        [Required(ErrorMessage = "Please enter age")]
        public int Age { get; set; }
        [Required(ErrorMessage = "Please choose gender")]
        public string Gender { get; set; }
        [Required(ErrorMessage = "Please enter position")]
        public string Position { get; set; }
        [Required(ErrorMessage = "Please enter office")]
        public string Office { get; set; }
        [Required(ErrorMessage = "Please enter salary")]
        public int Salary { get; set; }
        [Required(ErrorMessage = "Please choose profile image")]
        public string ProfilePicture { get; set; }
        public Employee()
        {
            FullName = FirstName + " " + LastName;
        }
    }
}

Step 3. Right-click on the project “Add” folder ViewModels and “Add” class EmployeeViewModel.

using Microsoft.AspNetCore.Http;
using System.ComponentModel.DataAnnotations;
namespace MvcCoreUploadAndDisplayImage_Demo.ViewModels
{
    public class EmployeeViewModel
    {
        [Required(ErrorMessage = "Please enter first name")]
        [Display(Name = "First Name")]
        public string FirstName { get; set; }
        [Required(ErrorMessage = "Please enter last name")]
        [Display(Name = "First Name")]
        public string LastName { get; set; }
        [Required(ErrorMessage = "Please enter age")]
        public int Age { get; set; }
        [Required(ErrorMessage = "Please choose gender")]
        public string Gender { get; set; }
        [Required(ErrorMessage = "Please enter position")]
        public string Position { get; set; }
        [Required(ErrorMessage = "Please enter office")]
        public string Office { get; set; }
        [Required(ErrorMessage = "Please enter salary")]
        public int Salary { get; set; }
        [Required(ErrorMessage = "Please choose profile image")]
        [Display(Name = "Profile Picture")]
        public IFormFile ProfileImage { get; set; }
    }
}

Step 4. Now click on ApplicationDbContext which is under the Data folder of your project. “Add” your Employee as DbSet.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using MvcCoreUploadAndDisplayImage_Demo.Models;

namespace MvcCoreUploadAndDisplayImage_Demo.Data
{
    public class ApplicationDbContext : IdentityDbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }

        public DbSet<Employee> Employees { get; set; }
    }
}

Step 5. Now create an images folder under the wwwroot folder of the project.

Step 6. Now go to tools, select Nuget package manager, then click on package manager console. It will bring the console window below in Visual Studio 2019. Now write the following commands to enable migration.

  • add-migration InitialModel (add migration can be anything you wish to)
  • update-database

Step 7. Now open HomeController which is added when we create a new project. Write the following code for Index and New IActionResult methods.

Controller Complete Code

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MvcCoreUploadAndDisplayImage_Demo.Data;
using MvcCoreUploadAndDisplayImage_Demo.Models;
using MvcCoreUploadAndDisplayImage_Demo.ViewModels;
using System;
using System.IO;
using System.Threading.Tasks;
namespace MvcCoreUploadAndDisplayImage_Demo.Controllers
{
    public class HomeController : Controller
    {
        private readonly ApplicationDbContext dbContext;
        private readonly IWebHostEnvironment webHostEnvironment;
        
        public HomeController(ApplicationDbContext context, IWebHostEnvironment hostEnvironment)
        {
            dbContext = context;
            webHostEnvironment = hostEnvironment;
        }
        public async Task<IActionResult> Index()
        {
            var employee = await dbContext.Employees.ToListAsync();
            return View(employee);
        }
        public IActionResult New()
        {
            return View();
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> New(EmployeeViewModel model)
        {
            if (ModelState.IsValid)
            {
                string uniqueFileName = UploadedFile(model);

                Employee employee = new Employee
                {
                    FirstName = model.FirstName,
                    LastName = model.LastName,
                    FullName = model.FirstName + " " + model.LastName,
                    Gender = model.Gender,
                    Age = model.Age,
                    Office = model.Office,
                    Position = model.Position,
                    Salary = model.Salary,
                    ProfilePicture = uniqueFileName,
                };
                dbContext.Add(employee);
                await dbContext.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View();
        }
        private string UploadedFile(EmployeeViewModel model)
        {
            string uniqueFileName = null;

            if (model.ProfileImage != null)
            {
                string uploadsFolder = Path.Combine(webHostEnvironment.WebRootPath, "images");
                uniqueFileName = Guid.NewGuid().ToString() + "_" + model.ProfileImage.FileName;
                string filePath = Path.Combine(uploadsFolder, uniqueFileName);
                using (var fileStream = new FileStream(filePath, FileMode.Create))
                {
                    model.ProfileImage.CopyTo(fileStream);
                }
            }
            return uniqueFileName;
        }
    }
}

Step 8. Right-click on the New IActionResult method. “Add” view with default name “New”. Write the following code.

@model MvcCoreUploadAndDisplayImage_Demo.ViewModels.EmployeeViewModel
@{
    ViewData["Title"] = "New";
}
<div class="col-md-10 mx-auto py-4">
    <div class="card">
        <div class="card-header bg-primary text-uppercase text-white">
            <h4>Add New </h4>
        </div>
        <div class="card-body">
            <form enctype="multipart/form-data" asp-action="New">
                <div class="row">
                    <div class="col-md-6">
                        <div class="form-group">
                            <label asp-for="FirstName" class="control-label"></label>
                            <input asp-for="FirstName" class="form-control" />
                            <span asp-validation-for="FirstName" class="text-danger"></span>
                        </div>
                    </div>
                    <div class="col-md-6">
                        <div class="form-group">
                            <label asp-for="LastName" class="control-label"></label>
                            <input asp-for="LastName" class="form-control" />
                            <span asp-validation-for="LastName" class="text-danger"></span>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-6">
                        <div class="form-group">
                            <label asp-for="Gender" class="control-label"></label>
                            <select asp-for="Gender" class="form-control">
                                <option value="">Choose Gender</option>
                                <option value="Male">Male</option>
                                <option value="Female">Female</option>
                            </select>
                            <span asp-validation-for="Gender" class="text-danger"></span>
                        </div>
                    </div>
                    <div class="col-md-6">
                        <div class="form-group">
                            <label asp-for="Age" class="control-label"></label>
                            <input asp-for="Age" class="form-control" />
                            <span asp-validation-for="Age" class="text-danger"></span>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-6">
                        <div class="form-group">
                            <label asp-for="Position" class="control-label"></label>
                            <input asp-for="Position" class="form-control" />
                            <span asp-validation-for="Position" class="text-danger"></span>
                        </div>
                    </div>
                    <div class="col-md-6">
                        <div class="form-group">
                            <label asp-for="Office" class="control-label"></label>
                            <input asp-for="Office" class="form-control" />
                            <span asp-validation-for="Office" class="text-danger"></span>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-6">
                        <div class="form-group">
                            <label asp-for="Salary" class="control-label"></label>
                            <input asp-for="Salary" class="form-control" />
                            <span asp-validation-for="Salary" class="text-danger"></span>
                        </div>
                    </div>
                    <div class="col-md-6">
                        <div class="form-group">
                            <label asp-for="ProfileImage" class="control-label"></label>
                            <div class="custom-file">
                                <input asp-for="ProfileImage" class="custom-file-input" id="customFile">
                                <label class="custom-file-label" for="customFile">Choose file</label>
                            </div>
                            <span asp-validation-for="ProfileImage" class="text-danger"></span>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <input type="submit" value="submit" class="btn btn-sm btn-primary rounded-0 text-uppercase" />
                    <a asp-action="Index" class="btn btn-sm btn-primary rounded-0 text-uppercase"><i class="fas fa-fast-backward"></i> Back to List</a>
                </div>
            </form>
        </div>
    </div>
</div>

@section scripts{
    <script type="text/javascript">
        // Add the following code if you want the name of the file appear on select
        $(".custom-file-input").on("change", function () {
            var fileName = $(this).val().split("\\").pop();
            $(this).siblings(".custom-file-label").addClass("selected").html(fileName);
        });
    </script>
}

Step 9. Right-click on the Index IActionResult method “Add” view with the default name “Index.” If you don't have it then write the following code.

@model IEnumerable<MvcCoreUploadAndDisplayImage_Demo.Models.Employee>
@{
    ViewData["Title"] = "Home Page";
}
<h4 class="text-center text-uppercase">List of employee</h4>
<p>
    <a asp-action="New" class="btn btn-sm btn-primary rounded-0 text-uppercase"><i class="fas fa-plus-circle"></i> Add New</a>
</p>
<table class="table table-bordered">
    <thead>
        <tr>
            <th>@Html.DisplayNameFor(model => model.FullName)</th>
            <th>@Html.DisplayNameFor(model => model.Gender)</th>
            <th>@Html.DisplayNameFor(model => model.Age)</th>
            <th>@Html.DisplayNameFor(model => model.Position)</th>
            <th>@Html.DisplayNameFor(model => model.Office)</th>
            <th>@Html.DisplayNameFor(model => model.Salary)</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var employee in Model)
        {
            <tr>
                <td>
                    <img src="~/images/@employee.ProfilePicture"
                         class="rounded-circle"
                         height="40" width="40"
                         asp-append-version="true" />
                    @employee.FullName
                </td>
                <td>@employee.Gender</td>
                <td>@employee.Age</td>
                <td>@employee.Office</td>
                <td>@employee.Position</td>
                <td>@employee.Salary</td>
            </tr>
        }
    </tbody>
</table>

Step 10. Build and Run your application by pressing ctrl+F5.

Add View

List of employee