Written by Mark Pringle | Last Updated on Thursday, November 17, 2022

MVC ASP.NET Version: 6.0 Tutorial Articles

This tutorial will show you how to create an image, photo, or file upload interface using ASP.NET Core 6.0 MVC. The file will be uploaded to a folder that is unique to the user. This tutorial requires that you have a basic knowledge of Microsoft SQL Server and Microsoft SQL Server Management Studio. 

File Upload Interface

IMPORTANT: This project assumes that you have already created a basic ASP.NET Core Web App project with an Authentication Type of Individual Accounts (It takes about 5 minutes. See how to do this). It also assumes that you have installed Microsoft SQL Server, created your database, and updated the applications connection string in the appsettings.json file.

Create the Database Table in Microsoft SQL Server Management Studio

First, using Microsoft SQL Server Management Studio, we will create a simple table to hold the image information. We will not use the Entity Framework Migration feature to build tables in the database. We will make the tables manually to see the relationship between the database table and the database model class. This table will have four columns:

  • ImageId - This column will contain the primary key of the uploaded file.
  • UserId – This column will contain the id of the user uploading the file.
  • ImageAltDescription – This column will contain a brief description of the image. This description will be used to create a unique file name for SEO purposes and can be used as an HTML alt attribute in the browser.
  • ImageFileName – This column will contain the photo's name generated using the ImageAltDescription.

database columns for file upload

Let’s name the table: Images.

sql server database table

Create a Database Model Class

Let’s go back to Visual Studio and create a database model class to mirror the Images table we just created.

Right-click on the Models folder. Select: Add ~ New Item…

Name the class the same name as the database table: Images.

right click models folder

We will add the four fields (properties) and data types to the Images class. We will then add a 5th property not mapped to a database column. It is used to receive the posted image when it is uploaded.

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

        [Required]
        public string? UserId { get; set; }

        [Required]
        [DisplayName("Image Alt Description")]
        public string? ImageAltDescription { get; set; }

        [DisplayName("Image File Name")]
        public string? ImageFileName { get; set; }

        [NotMapped]
        [DisplayName("Upload File")]
        public IFormFile? ImageFile { get; set; }
    }

Create an MVC Image Controller with CRUD Actions Using Scaffolding

Now that we have created the Images database model, we can use Scaffolding to create the MVC Images controller with CRUD actions.

To do this, right-click on the Controllers folder and select: Add ~ New Scaffolded Item…

  • Select and Add: MVC Controller with views, using Entity Framework
  • Select the Model Class you just created: Images
  • Select the existing Data context class
  • Click: Add

Add MVC Controller

After a few seconds, Scaffolding will have created the ImagesController.cs file and the associated Views. You can see the generated files by expanding both the Controllers and Views folders. The ImagesController.cs file will display in the project window after it has been created.

Scaffolded Files

Above the ImagesController class, within the ImagesController.cs file, add the [Authorize] attribute. This will ensure that only users with a registered account can access the upload image page. This is important because we will need to access their UserId and submit it with the rest of the data so that the uploaded images are associated with the current user.

authorize the controller

Save your project.

In the Package Manager Console, run the Update-Database command.

Update the Views to User the User Id of the Current User

When we upload an image, we need to send the current user's user ID to the database. For this tutorial, we will add code to the UserId form field to contain the current user’s user ID. This is typically hidden, but we will display it as a readonly form field. 

In the Views folder, open the Create.cshtml and Edit.cshtml pages and update the UserId input field code as shown below.

Add the @using System.Security.Claims; namespace as shown.

readonly value="@this.User.FindFirstValue(ClaimTypes.NameIdentifier)"

update the view with the userId

Save both files.

View What We Have Thus Far

You can start your project by running it with or without debugging.

If you have not done so, register for a new account by clicking on the Register link in the header. Enter your registration information and CONFIRM your account using the link on the Registration Confirmation page. Then, log in to the application.

Navigate to the /Images page. Here you will see an empty grid.

Click the Create New link to see the upload form.

You will notice your UserId in the associated field. However, something is missing: the image upload control.

missing upload field

We need to replace the Image File Name input control with an image/file upload control corresponding to the IFormFile ImageFile property in the database model class.

We are not going to worry about making the form pretty. We are just concerned with the functionality of this tutorial.

In the Create.cshtml file, replace the form group containing the ImageFileName with the upload control form group below.

            <div class="form-group">
                <label asp-for="ImageFile" class="control-label"></label>
                <input asp-for="ImageFile" accept="image/*" />
                <span asp-validation-for="ImageFile" class="text-danger"></span>
            </div>

replace with the upload control

Save the file and navigate back to the Create page. Now, you see the upload control.

The Upload Control

Adding the Remaining Functionality to the Image Upload Pages

Now, we must tell the create action how and where to save the image. We do this in the images controller within the create method.

Open the ImagesController.cs file and replace the existing POST create method with the following code.

Read the comments in the code below to see exactly what each part of the C# code is doing.

 [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create(Images images)
        {
            if (ModelState.IsValid)
            {
                //find the root directory of the application
                string wwwRootPath = _hostEnvironment.WebRootPath;

                //get the extension of the uploaded file
                string extension = Path.GetExtension(images.ImageFile.FileName);

                //Create a unique file name using the current date-time and the ImageAltDescription
                string fileName = images.ImageAltDescription.ToLower().Replace(' ', '-');
                string dateTime = DateTime.Now.ToString("yymmssfff");
                fileName = fileName + dateTime + extension;

                //add the new file name to the ImageFileName db field
                images.ImageFileName = fileName;

                ///check to see if this user's directory exists. If not, create it.
                string userPath = wwwRootPath + "/images/" + User.FindFirstValue(ClaimTypes.NameIdentifier) + "/";
                bool isExists = System.IO.Directory.Exists(userPath);
                if (!isExists)
                    System.IO.Directory.CreateDirectory(userPath);

                //ad the full path to the filename
                string path = Path.Combine(userPath, fileName);

                //save the file
                using (var fileStream = new FileStream(path, FileMode.Create))
                {
                    await images.ImageFile.CopyToAsync(fileStream);
                }

                //Insert record into the database
                _context.Add(images);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(images);
        }

Your upload file application is ready to use.

Upload a file and you will see the uploaded file in the wwwroot directory images folder. It will be in a folder that has your unique id.