Restricting Uploaded File Type and Size in ASP.NET Core MVC

Restricting Uploaded File Type and Size in ASP.NET Core MVC:

In this article, I will discuss How to Restrict Uploaded File Size and Type in an ASP.NET Core MVC Application with Examples. Please read our previous article discussing How to Implement File Handling in an ASP.NET Core MVC Application with Examples using Buffering and Streaming. Restricting the uploaded file size in ASP.NET Core MVC can be achieved through several methods. Here are the most common approaches:

Why Do We Need to Restrict File Type and File Size in Web Applications?

When allowing file uploads in web applications, it is crucial to impose restrictions on file type and file size for several reasons:

  • Security Concerns: Allowing unrestricted file type uploads may lead to security vulnerabilities, such as uploading malicious scripts (e.g., .exe, .bat, .php, etc.). By restricting file types, we minimize the risk of executing harmful code.
  • Storage Management and Performance Optimization: Unrestricted large file uploads can lead to excessive disk usage, affecting server performance. Large file uploads can degrade the application’s performance, slowing down the system and increasing server load. Limiting the file size Limiting file size and format ensures faster upload and download times, leading to a better user experience.
  • Data Integrity and Compatibility: Some applications expect specific file formats. Restricting to known file types ensures that uploaded files can be processed and used effectively by the application. Informing users about allowed file types and sizes improves usability and prevents frustration when uploads fail later.

What are File Extensions and MIME Types?

A file extension represents the type of file, while a MIME type (Multipurpose Internet Mail Extensions) describes the file’s content. The following are some of the common file extensions and their corresponding MIME types:

File Extensions

A file extension is the suffix at the end of a filename, such as:

  1. .jpg – Commonly used for JPEG images
  2. .png – Portable Network Graphics image
  3. .gif – Graphics Interchange Format image
  4. .pdf – Portable Document Format
  5. .docx – Microsoft Word document
  6. .xls (.xlsx) – Microsoft Excel Files
  7. .txt – Text Files
MIME Types

MIME (Multipurpose Internet Mail Extensions) types are standardized identifiers used on the Internet to indicate the nature and format of a file, such as:

  1. image/jpeg – for JPEG images
  2. image/png – for PNG images
  3. image/gif – for GIF images
  4. application/pdf – for PDF documents
  5. application/msword – for DOCX files
  6. application/vnd.ms-excel – for Excel Files
  7. text/plain – for Text Files

Note: It is good practice to validate both the file extension (to check the filename) and the MIME type (to check the actual content type).

Real-Time Use Case Example

Many applications, such as banking, government portals, job application sites, and KYC (Know Your Customer) processes, require users to upload their profile picture (as an image file) and multiple identity proofs (such as a passport or driver’s license in PDF format) for verification. Examples include:

  • Banking Applications: Users submit a profile photo and multiple identity proofs like Aadhar, Passport, and PAN card.
  • Government Portals: Verification for official documents requires multiple ID proofs.
  • Job Portals: Profile verification with passport, driver’s license, and other documents.
Real-Time Example: Restrict File Uploads in ASP.NET Core MVC

Now, we will build a complete real‑time application using ASP.NET Core MVC and EF Core (Code First approach) with the following features:

  • A user uploads one profile photo (an image file).
  • A user uploads multiple identity proofs (each a PDF file).
  • While Uploading the Identity proof, the Identity Proof Name needs to be chosen from a system‑provided drop‑down list (for example, Passport, Driver License, National ID, Voter ID, Aadhar, etc.).
  • The files will be stored in the server’s file system.
  • The application will save file metadata (such as File Name, MIME Type, and File Size) in the database.
  • Each identity proof record includes a verification status (managed later by an admin).

Let us first understand the pictorial flow of the application that we will develop.

Profile List Page:

The User Profiles Page displays a list of all user profiles along with their uploaded identity proofs, as shown in the below image:

How to Restrict Uploaded File Size and Type in an ASP.NET Core MVC

Key Features:
  • It displays the full name of each user, their profile picture, and a list of uploaded identity proofs (such as Aadhar and PAN).
  • Each identity proof includes file details like file size and type.
  • The current verification status (e.g., Pending, Verified, Rejected) of each document is shown along with an action button (e.g., Verify), allowing admins to verify the document.
  • The table also displays the date the profile was created.
Profile Create Page:

The Profile Create Page allows users to create a profile and upload identity proofs, as shown in the image below:

How to Restrict Uploaded File Size and File Type in an ASP.NET Core MVC Application

Key Features:
  • Users must provide their full name and upload a profile picture (with size and format constraints like JPG, PNG, or GIF).
  • The identity proofs section allows users to upload one or more documents, each with a dropdown list to select the type of proof (e.g., Aadhar, Passport, etc.) and an option to upload the PDF file.
  • There is a button to add more identity proofs and a Submit Profile button to complete the process.
  • On the right side, there is a guidelines section explaining how to create the profile, including instructions for the profile picture and document upload.
Verify Identity Proof Page:

The Verify Identity Proof Page allows administrators to review and verify user-uploaded identity proofs, as shown in the below image:

Restricting Uploaded File Type and Size in ASP.NET Core MVC

Key Features:
  • It displays details of the selected identity proof, including the proof type, file name, file type, and file size.
  • The new verification status can be selected from a dropdown (e.g., Pending, Verified, Rejected), and the admin can add comments regarding the verification status.
  • There are options to submit the verification or go back to the list of profiles.
Create a New ASP.NET Core MVC Project and Install EF Core Packages

Open Visual Studio and create a new ASP.NET Core Web App (Model-View-Controller) project and give the project name as FileHandlingDemo. Once you create the Project, Install the necessary EF Core Packages targeting the SQL Server database. Please execute the below commands in the Visual Studio Package Manager Console to install the Package:

  • Install-Package Microsoft.EntityFrameworkCore.SqlServer
  • Install-Package Microsoft.EntityFrameworkCore.Tools
Creating Data Models

Models represent our domain data and are used by Entity Framework Core (EF Core) to create database tables and perform CRUD operations. In our application, there are four primary models:

ProofType

Create a class file named ProofType.cs within the Models folder, and then copy and paste the following code. It acts as a master (lookup) table that lists all allowed identity proof types (e.g., Passport, Driver License, etc.).

namespace FileHandlingDemo.Models
{
    // Master table for proof types
    public class ProofType
    {
        public int Id { get; set; }      // Primary key
        public string Name { get; set; } // Proof type name (e.g., Passport, Driver License, etc.)
    }
}
VerificationStatus

Create a class file named VerificationStatus.cs within the Models folder, and then copy and paste the following code. It serves as a master table that defines the possible statuses (e.g., Pending, Verified, Rejected) for identity proof verification.

namespace FileHandlingDemo.Models
{
    // Master table for verification statuses
    public class VerificationStatus
    {
        public int Id { get; set; }        // Primary key
        public string Name { get; set; }   // Status name (e.g., Pending, Verified, Rejected)
    }
}
UserProfile

Create a class file named UserProfile.cs within the Models folder, and then copy and paste the following code. It represents a user’s profile, including personal details, a single profile picture, and a collection of identity proofs.

namespace FileHandlingDemo.Models
{
    // Represents a user profile with a single profile picture and multiple identity proofs.
    public class UserProfile
    {
        public int Id { get; set; } // Primary key

        public string FullName { get; set; } // User’s full name

        // Profile picture file metadata
        public string ProfilePictureFileName { get; set; } // The saved file name on disk
        public string ProfilePictureFileType { get; set; } // MIME type (e.g., image/jpeg)
        public long ProfilePictureFileSize { get; set; }     // File size in bytes

        public DateTime CreatedOn { get; set; } // When the profile was created

        // Navigation property – a user may have multiple identity proofs.
        public virtual ICollection<IdentityProof> IdentityProofs { get; set; }
    }
}
IdentityProof

Create a class file named IdentityProof.cs within the Models folder, and then copy and paste the following code. It represents a single document that serves as proof of identity uploaded by the user.

namespace FileHandlingDemo.Models
{
    // Represents one identity proof document uploaded by the user.
    public class IdentityProof
    {
        public int Id { get; set; } // Primary key

        // Foreign key for the master table ProofType
        public int ProofTypeId { get; set; }
        public ProofType ProofType { get; set; } // Navigation property to ProofType

        // File metadata for the identity proof
        public string FileName { get; set; } // The saved file name on disk
        public string FileType { get; set; } // MIME type (e.g., application/pdf)
        public long FileSize { get; set; }   // File size in bytes

        // Verification details (managed by admin)
        // Foreign key for the master table VerificationStatus
        public int VerificationStatusId { get; set; }
        public VerificationStatus VerificationStatus { get; set; } // Navigation property
        public DateTime UploadedOn { get; set; } // When the proof was uploaded
        public string? AdminComments { get; set; } // Optional comments by admin

        // Foreign key – relates this identity proof to a specific user profile.
        public int UserProfileId { get; set; }
        public virtual UserProfile UserProfile { get; set; }
    }
}
View Models

View Models are explicitly designed to transfer data between your views and controllers. They often combine or reshape data from multiple models and add validation attributes. Please create a new folder named ViewModels in the project root directory, where we will create all our View Models.

IdentityProofUploadViewModel

Create a class file named IdentityProofUploadViewModel.cs within the ViewModels folder, and then copy and paste the following code. It captures the data for one identity proof from the upload form.

using System.ComponentModel.DataAnnotations;

namespace FileHandlingDemo.ViewModels
{
    // Captures one identity proof’s data from the upload form.
    public class IdentityProofUploadViewModel
    {
        [Required(ErrorMessage = "Please select a proof type.")]
        [Display(Name = "Proof Type")]
        public int SelectedProofTypeId { get; set; } // Selected Proof Type ID from the drop-down

        [Required(ErrorMessage = "Please select a file for the identity proof.")]
        [Display(Name = "Proof File (PDF)")]
        public IFormFile File { get; set; }
    }
}
UserProfileUploadViewModel

Create a class file named UserProfileUploadViewModel.cs within the ViewModels folder, and then copy and paste the following code. It collects all the data needed to create a new user profile.

using System.ComponentModel.DataAnnotations;

namespace FileHandlingDemo.ViewModels
{
    // Captures the complete user profile creation data.
    public class UserProfileUploadViewModel
    {
        [Required(ErrorMessage = "Full name is required.")]
        [Display(Name = "Full Name")]
        public string FullName { get; set; }

        [Required(ErrorMessage = "Please select a profile picture.")]
        [Display(Name = "Profile Picture (Image file)")]
        public IFormFile ProfilePicture { get; set; }

        // A list to hold multiple identity proofs.
        [Display(Name = "Identity Proofs (PDF files)")]
        public List<IdentityProofUploadViewModel> IdentityProofs { get; set; } = new List<IdentityProofUploadViewModel>();
    }
}
IdentityProofVerificationViewModel

Create a class file named IdentityProofVerificationViewModel.cs within the ViewModels folder, and then copy and paste the following code. It is used in the admin interface to review and update the verification status of identity proof.

using System.ComponentModel.DataAnnotations;

namespace FileHandlingDemo.ViewModels
{
    // Used in the admin interface to review and update identity proofs.
    public class IdentityProofVerificationViewModel
    {
        public int Id { get; set; }

        [Display(Name = "Proof Type")]
        public string? ProofTypeName { get; set; }  // Name from the ProofType master table

        [Display(Name = "File Name")]
        public string? FileName { get; set; }

        [Display(Name = "File Type")]
        public string? FileType { get; set; }

        [Display(Name = "File Size (bytes)")]
        public long? FileSize { get; set; }

        [Display(Name = "Uploaded On")]
        public DateTime? UploadedOn { get; set; }

        [Display(Name = "Current Verification Status")]
        public string? VerificationStatusName { get; set; } // Name from the VerificationStatus master table

        [Required(ErrorMessage = "Please select a new status.")]
        [Display(Name = "New Verification Status")]
        public int NewVerificationStatusId { get; set; }  // New status ID (to be chosen by admin)

        [Display(Name = "Admin Comments")]
        public string? AdminComments { get; set; }
    }
}
DB Context

First, create a folder named Data in the project root directory. Then, create a class file named ApplicationDbContext.cs within the Data folder and copy and paste the following code. It acts as the bridge between our application and the database. It also manages database connections, tracks changes, and provides CRUD operations.

using FileHandlingDemo.Models;
using Microsoft.EntityFrameworkCore;

namespace FileHandlingDemo.Data
{
    // EF Core context that registers the models.
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }

        // Seed master tables using HasData.
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            // Seed ProofType master table.
            modelBuilder.Entity<ProofType>().HasData(
                new ProofType { Id = 1, Name = "Passport" },
                new ProofType { Id = 2, Name = "Driver License" },
                new ProofType { Id = 3, Name = "National ID" },
                new ProofType { Id = 4, Name = "Voter ID" },
                new ProofType { Id = 5, Name = "Aadhar" },
                new ProofType { Id = 6, Name = "Pan" },
                new ProofType { Id = 7, Name = "Other" }
            );

            // Seed VerificationStatus master table.
            modelBuilder.Entity<VerificationStatus>().HasData(
                new VerificationStatus { Id = 1, Name = "Pending" },
                new VerificationStatus { Id = 2, Name = "Verified" },
                new VerificationStatus { Id = 3, Name = "Rejected" }
            );
        }

        public DbSet<UserProfile> UserProfiles { get; set; }
        public DbSet<IdentityProof> IdentityProofs { get; set; }
        public DbSet<ProofType> ProofTypes { get; set; }
        public DbSet<VerificationStatus> VerificationStatuses { get; set; }
    }
}

Note: In the OnModelCreating method, the master tables (ProofType and VerificationStatus) are seeded with initial data to automatically populate dropdowns in the views.

Controllers

Controllers process user requests and return responses. That means it contains the logic for handling HTTP requests, interacting with the model layer, and returning appropriate views.

UserProfileController

The UserProfileController manages the profile creation process. It validates file types and sizes, saves files to disk, and creates database records. In this example, the restrictions are as follows:

  • Profile Photo: Allowed image files (jpg, jpeg, png, gif) up to 2 MB.
  • Identity Proofs: Allowed PDF files up to 5 MB each.

Create a new MVC Empty Controller named UserProfileController within the Controllers folder and then copy and paste the following code. This controller manages all operations related to user profiles and identity proofs. Handles file validations, file saving (to the server’s filesystem), and database record creation/updating.

using FileHandlingDemo.Data;
using FileHandlingDemo.Models;
using FileHandlingDemo.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;

namespace FileHandlingDemo.Controllers
{
    public class UserProfileController : Controller
    {
        private readonly ApplicationDbContext _context;
        private readonly IWebHostEnvironment _webHostEnvironment;
        private readonly ILogger<UserProfileController> _logger;

        // Allowed file extensions and MIME types for profile pictures (images)
        private readonly string[] _allowedImageExtensions = { ".jpg", ".jpeg", ".png", ".gif" };
        private readonly string[] _allowedImageMimeTypes = { "image/jpeg", "image/png", "image/gif" };
        private const long _profilePicSizeLimit = 2 * 1024 * 1024; // 2 MB

        // Allowed file extension and MIME type for identity proofs (PDF)
        private readonly string[] _allowedPdfExtensions = { ".pdf" };
        private readonly string[] _allowedPdfMimeTypes = { "application/pdf" };
        private const long _identityProofSizeLimit = 5 * 1024 * 1024; // 5 MB

        public UserProfileController(ApplicationDbContext context, IWebHostEnvironment webHostEnvironment, ILogger<UserProfileController> logger)
        {
            _context = context;
            _webHostEnvironment = webHostEnvironment;
            _logger = logger;
        }

        // GET: /UserProfile/Index
        // Lists all user profiles.
        public IActionResult Index()
        {
            // Eager-load IdentityProofs and their related master data.
            var profiles = _context.UserProfiles
                .Select(p => new UserProfile
                {
                    Id = p.Id,
                    FullName = p.FullName,
                    ProfilePictureFileName = p.ProfilePictureFileName,
                    CreatedOn = p.CreatedOn,
                    IdentityProofs = p.IdentityProofs.Select(ip => new IdentityProof
                    {
                        Id = ip.Id,
                        FileName = ip.FileName,
                        FileType = ip.FileType,
                        FileSize = ip.FileSize,
                        UploadedOn = ip.UploadedOn,
                        VerificationStatus = ip.VerificationStatus,
                        ProofType = ip.ProofType
                    }).ToList()
                }).ToList();

            return View(profiles);
        }

        // GET: /UserProfile/Create
        // Renders the form to create a new user profile.
        public IActionResult Create()
        {
            // Load the master list of proof types from the database.
            var proofTypes = _context.ProofTypes.ToList();
            ViewBag.ProofTypes = new SelectList(proofTypes, "Id", "Name");

            // Initialize with one empty identity proof field.
            var model = new UserProfileUploadViewModel();
            model.IdentityProofs.Add(new IdentityProofUploadViewModel());
            return View(model);
        }

        // POST: /UserProfile/Create
        // Processes the submitted form.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create(UserProfileUploadViewModel model)
        {
            // Re-populate the ProofTypes list for the dropdown in case of an error.
            ViewBag.ProofTypes = new SelectList(_context.ProofTypes.ToList(), "Id", "Name");

            // Check if the overall model state is valid.
            if (!ModelState.IsValid)
            {
                return View(model);
            }

            // --- Server-Side Duplicate Check for Identity Proof Types ---
            if (model.IdentityProofs != null && model.IdentityProofs.Any())
            {
                // Only consider entries that have a file uploaded.
                var selectedProofTypeIds = model.IdentityProofs
                    .Where(ip => ip.File != null && ip.File.Length > 0)
                    .Select(ip => ip.SelectedProofTypeId)
                    .ToList();

                // If the number of unique proof type IDs is less than the number provided, then duplicates exist.
                if (selectedProofTypeIds.Count != selectedProofTypeIds.Distinct().Count())
                {
                    ModelState.AddModelError("IdentityProofs", "Each identity proof must have a unique proof type.");
                    return View(model);
                }
            }

            // --- Validate Profile Picture ---
            if (model.ProfilePicture == null || model.ProfilePicture.Length == 0)
            {
                ModelState.AddModelError("ProfilePicture", "Profile picture is required.");
                return View(model);
            }
            if (model.ProfilePicture.Length > _profilePicSizeLimit)
            {
                ModelState.AddModelError("ProfilePicture", "Profile picture exceeds the maximum allowed size of 2 MB.");
                return View(model);
            }
            var profilePicExt = Path.GetExtension(model.ProfilePicture.FileName).ToLowerInvariant();
            if (string.IsNullOrEmpty(profilePicExt) || !_allowedImageExtensions.Contains(profilePicExt))
            {
                ModelState.AddModelError("ProfilePicture", "Invalid file extension for profile picture.");
                return View(model);
            }
            if (!_allowedImageMimeTypes.Contains(model.ProfilePicture.ContentType))
            {
                ModelState.AddModelError("ProfilePicture", "Invalid MIME type for profile picture.");
                return View(model);
            }

            // --- Prepare Folders for Saving Files ---
            var uploadsRoot = Path.Combine(_webHostEnvironment.WebRootPath, "uploads");
            var profilePicFolder = Path.Combine(uploadsRoot, "profile_pictures");
            var identityProofFolder = Path.Combine(uploadsRoot, "identity_proofs");

            if (!Directory.Exists(profilePicFolder))
                Directory.CreateDirectory(profilePicFolder);
            if (!Directory.Exists(identityProofFolder))
                Directory.CreateDirectory(identityProofFolder);

            // --- Save the Profile Picture ---
            var profilePicFileName = Guid.NewGuid().ToString() + profilePicExt;
            var profilePicPath = Path.Combine(profilePicFolder, profilePicFileName);
            using (var stream = new FileStream(profilePicPath, FileMode.Create))
            {
                await model.ProfilePicture.CopyToAsync(stream);
            }

            // --- Create the UserProfile Entity ---
            var userProfile = new UserProfile
            {
                FullName = model.FullName,
                ProfilePictureFileName = profilePicFileName,
                ProfilePictureFileType = model.ProfilePicture.ContentType,
                ProfilePictureFileSize = model.ProfilePicture.Length,
                CreatedOn = DateTime.Now,
                IdentityProofs = new List<IdentityProof>()
            };

            // --- Process Each Identity Proof Entry ---
            if (model.IdentityProofs != null)
            {
                foreach (var proofModel in model.IdentityProofs)
                {
                    // Skip entries where no file is provided.
                    if (proofModel.File == null || proofModel.File.Length == 0)
                        continue;

                    // Validate file size for identity proof.
                    if (proofModel.File.Length > _identityProofSizeLimit)
                    {
                        ModelState.AddModelError("IdentityProofs", "One of the identity proof files exceeds the maximum allowed size of 5 MB.");
                        return View(model);
                    }
                    // Validate file extension.
                    var proofExt = Path.GetExtension(proofModel.File.FileName).ToLowerInvariant();
                    if (string.IsNullOrEmpty(proofExt) || !_allowedPdfExtensions.Contains(proofExt))
                    {
                        ModelState.AddModelError("IdentityProofs", "Invalid file extension for identity proof. Only PDF files are allowed.");
                        return View(model);
                    }
                    // Validate MIME type.
                    if (!_allowedPdfMimeTypes.Contains(proofModel.File.ContentType))
                    {
                        ModelState.AddModelError("IdentityProofs", "Invalid MIME type for identity proof. Only PDF files are allowed.");
                        return View(model);
                    }

                    // Save the identity proof file.
                    var proofFileName = Guid.NewGuid().ToString() + proofExt;
                    var proofFilePath = Path.Combine(identityProofFolder, proofFileName);
                    using (var stream = new FileStream(proofFilePath, FileMode.Create))
                    {
                        await proofModel.File.CopyToAsync(stream);
                    }

                    // Create a new IdentityProof entity.
                    var identityProof = new IdentityProof
                    {
                        // Map the selected proof type ID from the view model.
                        ProofTypeId = proofModel.SelectedProofTypeId,
                        FileName = proofFileName,
                        FileType = proofModel.File.ContentType,
                        FileSize = proofModel.File.Length,
                        // Set the initial verification status as Pending (assuming its ID is 1 in your VerificationStatuses master table).
                        VerificationStatusId = 1,
                        UploadedOn = DateTime.Now
                    };

                    // Add this identity proof to the user profile.
                    userProfile.IdentityProofs.Add(identityProof);
                }
            }

            // --- Save the UserProfile (and its IdentityProofs) to the Database ---
            _context.UserProfiles.Add(userProfile);
            await _context.SaveChangesAsync();

            // Redirect to the Index action after successful creation.
            return RedirectToAction("Index");
        }


        // GET: /UserProfile/Verify/{id}
        // Renders a form to verify (approve/reject) a specific identity proof.
        public IActionResult Verify(int id)
        {
            var proof = _context.IdentityProofs
                .Include(ip => ip.ProofType)
                .Include(ip => ip.VerificationStatus)
                .FirstOrDefault(p => p.Id == id);
            if (proof == null)
                return NotFound();

            var model = new IdentityProofVerificationViewModel
            {
                Id = proof.Id,
                ProofTypeName = proof.ProofType.Name,
                FileName = proof.FileName,
                FileType = proof.FileType,
                FileSize = proof.FileSize,
                UploadedOn = proof.UploadedOn,
                VerificationStatusName = proof.VerificationStatus.Name,
                // Default new status as current (you may want to force a new selection)
                NewVerificationStatusId = proof.VerificationStatusId
            };

            // Load the master verification statuses to populate the drop-down.
            ViewBag.VerificationStatuses = new SelectList(_context.VerificationStatuses.ToList(), "Id", "Name");

            return View(model);
        }

        // POST: /UserProfile/Verify
        // Processes the verification update.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Verify(IdentityProofVerificationViewModel model)
        {
            if (!ModelState.IsValid)
            {
                ViewBag.VerificationStatuses = new SelectList(_context.VerificationStatuses.ToList(), "Id", "Name");
                return View(model);
            }

            var proof = _context.IdentityProofs.FirstOrDefault(p => p.Id == model.Id);
            if (proof == null)
                return NotFound();

            // Update verification status and admin comments.
            proof.VerificationStatusId = model.NewVerificationStatusId;
            proof.AdminComments = model.AdminComments;

            _context.SaveChanges();

            return RedirectToAction("Index");
        }
    }
}
Controller Action Methods:
Index (GET)

Retrieves and displays a list of user profiles along with their profile pictures and identity proofs. It uses eager loading (via Include or projection) to bring in related data (such as proof types and verification statuses) to be shown in the view.

Create (GET)

Renders the form to create a new user profile. It loads the master list of proof types from the database and populates a SelectList for dropdowns. Initializes the view model with one empty identity proof field.

Create (POST)

Processes the submitted form data to create a new user profile.

  • It checks that the profile picture and identity proof files conform to allowed types (images for the profile picture and PDFs for proofs) and size limits (2 MB and 5 MB, respectively).
  • Verifies that no duplicate proof type selections have been made.
  • Saves files to designated folders on the server (e.g., uploads/profile_pictures and uploads/identity_proofs).
  • Creates a UserProfile entity, populates its properties, adds identity-proof entities to its collection, and saves the entire object graph to the database.
Verify (GET)

Displays a form that lets an admin review a specific identity proof. Loads the specific identity proof and its associated master data (proof type and verification status). Populates a view model (IdentityProofVerificationViewModel) with current details and loads a list of available verification statuses dropdown.

Verify (POST)

Processes the verification form submitted by the admin to update the identity proof’s verification status. Validates the submitted data. Updates the VerificationStatusId and AdminComments for the selected identity proof record in the database.

Creating Views

Views define the user interface and render the data provided by the controller. They use Razor syntax to integrate with the models and view models.

User Profile Creation View

Create a view named Create.cshtml within the Views/UserProfile folder, and then copy and paste the following code. This view provides a form for users to enter their full name, upload a profile picture, and add one or more identity proofs.

@model FileHandlingDemo.ViewModels.UserProfileUploadViewModel

@{
    ViewData["Title"] = "Create User Profile";
}

<div class="container my-5">
    <div class="row">
        <!-- Left Column: Profile Creation Form -->
        <div class="col-lg-7">
            <div class="card shadow">
                <div class="card-header bg-primary text-white">
                    <h3 class="mb-0">Create Your Profile</h3>
                </div>
                <div class="card-body">
                    <!-- Profile Form -->
                    <form id="userProfileForm" asp-controller="UserProfile" asp-action="Create" method="post" enctype="multipart/form-data">
                        @Html.AntiForgeryToken()
                        <!-- Full Name Field -->
                        <div class="mb-3">
                            <label asp-for="FullName" class="form-label">Full Name</label>
                            <input asp-for="FullName" class="form-control" placeholder="John Doe" />
                            <span asp-validation-for="FullName" class="text-danger"></span>
                        </div>

                        <!-- Profile Picture Field -->
                        <div class="mb-3">
                            <label asp-for="ProfilePicture" class="form-label">Profile Picture</label>
                            @* <input asp-for="ProfilePicture" type="file" accept="image/jpg, image/jpeg, image/png, image/gif" class="form-control custom-file-input" /> *@
                            <input asp-for="ProfilePicture" type="file" accept=".jpg,.jpeg,.png,.gif" class="form-control custom-file-input" />
                    @*         <input asp-for="ProfilePicture" type="file" class="form-control custom-file-input" /> *@
                            <span asp-validation-for="ProfilePicture" class="text-danger"></span>
                        </div>

                        <!-- Identity Proofs Section -->
                        <h4 class="mt-4">Identity Proofs</h4>
                        <hr />

                        <!-- Container for Identity Proof Entries -->
                        <div id="identityProofsContainer">
                            @for (int i = 0; i < Model.IdentityProofs.Count; i++)
                            {
                                <div class="identity-proof-entry border rounded p-3 mb-3">
                                    <div class="mb-2">
                                        <h5 class="mb-0">Proof @(i + 1)</h5>
                                    </div>
                                    <!-- Proof Type Dropdown -->
                                    <div class="mb-3">
                                        <label asp-for="IdentityProofs[i].SelectedProofTypeId" class="form-label">Proof Type</label>
                                        <select asp-for="IdentityProofs[i].SelectedProofTypeId" class="form-select" asp-items="(SelectList)ViewBag.ProofTypes">
                                            <option value="">-- Select Proof Type --</option>
                                        </select>
                                        <span asp-validation-for="IdentityProofs[i].SelectedProofTypeId" class="text-danger"></span>
                                    </div>
                                    <!-- Proof File Upload -->
                                    <div class="mb-3">
                                        <label asp-for="IdentityProofs[i].File" class="form-label">Proof File (PDF)</label>
                                        <input asp-for="IdentityProofs[i].File" type="file" accept=".pdf" class="form-control custom-file-input" />
                                       @*  <input asp-for="IdentityProofs[i].File" type="file" accept="application/pdf" class="form-control custom-file-input" /> *@
@*                                         <input asp-for="IdentityProofs[i].File" type="file" class="form-control custom-file-input" /> *@
                                        <span asp-validation-for="IdentityProofs[i].File" class="text-danger"></span>
                                    </div>
                                </div>
                            }
                        </div>

                        <!-- Button to Add Additional Identity Proof -->
                        <div class="mb-3">
                            <button type="button" id="addProofBtn" class="btn btn-secondary">
                                <i class="bi bi-plus-circle"></i> Add Identity Proof
                            </button>
                        </div>

                        <!-- Submit Button -->
                        <div class="text-end">
                            <button type="submit" class="btn btn-primary">
                                <i class="bi bi-check-circle"></i> Submit Profile
                            </button>
                        </div>
                    </form>
                </div>
            </div>
        </div>

        <!-- Right Column: Profile Creation Guidelines -->
        <div class="col-lg-5 d-none d-lg-block">
            <div class="card shadow border-0">
                <div class="card-body" style="text-align: justify;">
                    <h4 class="card-title">Profile Creation Guidelines</h4>
                    <ul>
                        <li>
                            <strong>Full Name:</strong> Enter your complete legal name exactly as it appears on your identification.
                        </li>
                        <li>
                            <strong>Profile Picture:</strong> Upload a clear and recent photograph in JPG, PNG, or GIF format (max 2MB).
                        </li>
                        <li>
                            <strong>Identity Proofs:</strong> Upload each identity document in PDF format (max 5MB per file). Ensure that each document type is unique—duplicate selections are not allowed.
                        </li>
                    </ul>
                    <p class="text-muted">For any assistance, please contact our support team.</p>
                    <a href="mailto:support@example.com" class="btn btn-outline-primary">
                        <i class="bi bi-envelope-fill"></i> Contact Support
                    </a>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- Hidden Template for New Identity Proof Entry -->
<script id="identityProofTemplate" type="text/template">
    <div class="identity-proof-entry border rounded p-3 mb-3">
        <div class="mb-2">
            <h5 class="mb-0">Proof __INDEX__</h5>
        </div>
        <div class="mb-3">
            <label for="IdentityProofs___INDEX___SelectedProofTypeId" class="form-label">Proof Type</label>
            <select class="form-select" id="IdentityProofs___INDEX___SelectedProofTypeId" name="IdentityProofs[__INDEX__].SelectedProofTypeId">
                <option value="">-- Select Proof Type --</option>
                    @foreach (var item in (SelectList)ViewBag.ProofTypes)
                    {
                        <option value="@item.Value">@item.Text</option>
                    }
            </select>
            <span class="text-danger field-validation-valid" data-valmsg-for="IdentityProofs[__INDEX__].SelectedProofTypeId" data-valmsg-replace="true"></span>
        </div>
        <div class="mb-3">
            <label for="IdentityProofs___INDEX___File" class="form-label">Proof File (PDF)</label>
            <input class="form-control custom-file-input" accept=".pdf" id="IdentityProofs___INDEX___File" name="IdentityProofs[__INDEX__].File" type="file" />
            <span class="text-danger field-validation-valid" data-valmsg-for="IdentityProofs[__INDEX__].File" data-valmsg-replace="true"></span>
        </div>
    </div>
</script>

<!-- Modal Popup for Error Messages -->
<div class="modal fade" id="errorModal" tabindex="-1" aria-labelledby="errorModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title text-danger" id="errorModalLabel">Error</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <!-- The error message text is now styled with text-danger -->
            <div class="modal-body text-danger" id="modalErrorMessage">
                <!-- Error message will be injected here -->
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">OK</button>
            </div>
        </div>
    </div>
</div>

@section Scripts {
    <script>
        $(document).ready(function () {
            // Allowed file types and size limits
            var allowedProfileExtensions = ['.jpg', '.jpeg', '.png', '.gif'];
            var maxProfileSize = 2 * 1024 * 1024; // 2 MB

            var allowedProofExtension = '.pdf';
            var maxProofSize = 5 * 1024 * 1024;  // 5 MB

            // Utility: get file extension from filename
            function getFileExtension(filename) {
                return filename.substring(filename.lastIndexOf('.')).toLowerCase();
            }

            // Validate file inputs when changed
            $(document).on('change', 'input[type="file"]', function () {
                var $this = $(this);
                var file = this.files[0];
                if (file) {
                    var ext = getFileExtension(file.name);
                    // Check if this is the Profile Picture
                    if ($this.attr('name') === 'ProfilePicture') {
                        if ($.inArray(ext, allowedProfileExtensions) === -1) {
                            showErrorModal("Invalid file type for Profile Picture. Allowed types: JPG, JPEG, PNG, GIF.");
                            $this.val(''); // Reset the file input
                        } else if (file.size > maxProfileSize) {
                            showErrorModal("Profile Picture size exceeds the 2 MB limit.");
                            $this.val('');
                        }
                    } else {
                        // Otherwise, it's an Identity Proof file (PDF only)
                        if (ext !== allowedProofExtension) {
                            showErrorModal("Invalid file type for Identity Proof. Only PDF files are allowed.");
                            $this.val('');
                        } else if (file.size > maxProofSize) {
                            showErrorModal("Identity Proof file size exceeds the 5 MB limit.");
                            $this.val('');
                        }
                    }
                }
            });

            // Check for duplicate identity proof selections on change using event delegation
            $(document).on('change', 'select[name*="SelectedProofTypeId"]', function () {
                var $currentSelect = $(this);
                var currentVal = $currentSelect.val();
                if (currentVal) {
                    var duplicateFound = false;
                    $('select[name*="SelectedProofTypeId"]').not($currentSelect).each(function () {
                        if ($(this).val() === currentVal) {
                            duplicateFound = true;
                            return false; // break loop
                        }
                    });
                    if (duplicateFound) {
                        showErrorModal("Duplicate identity proof types are not allowed. Please select a unique type.");
                        // Reset the current select to its default empty value
                        $currentSelect.val('');
                    }
                }
            });

            // Also check duplicates on form submission
            $('#userProfileForm').on('submit', function (e) {
                var selectedValues = {};
                var duplicateFound = false;
                $('select[name*="SelectedProofTypeId"]').each(function () {
                    var val = $(this).val();
                    if (val) {
                        if (selectedValues[val]) {
                            duplicateFound = true;
                            return false;
                        } else {
                            selectedValues[val] = true;
                        }
                    }
                });
                if (duplicateFound) {
                    showErrorModal("Duplicate identity proof types are not allowed. Please select unique types for each.");
                    e.preventDefault();
                }
            });

            // Add new identity proof entry dynamically using jQuery
            $('#addProofBtn').on('click', function () {
                var $container = $('#identityProofsContainer');
                var index = $container.find('.identity-proof-entry').length;
                var template = $('#identityProofTemplate').html();
                var newEntryHtml = template.replace(/__INDEX__/g, index);
                $container.append(newEntryHtml);
            });

            // Update custom file input labels on change
            $(document).on('change', '.custom-file-input', function () {
                var fileName = $(this).val().split('\\').pop();
                $(this).siblings('.custom-file-label').html(fileName);
            });

            // Function to show the error modal with a given message
            function showErrorModal(message) {
                $('#modalErrorMessage').text(message);
                $('#errorModal').modal('show');
            }
        });
    </script>
}
User Profile List View

Create a view named Index.cshtml within the Views/UserProfile folder, copy and paste the following code. This view displays a list of all user profiles with details such as the user’s name, profile picture, uploaded identity proofs, and current verification status.

@model IEnumerable<FileHandlingDemo.Models.UserProfile>

@{
    ViewData["Title"] = "User Profiles";
}

<div class="container my-5">
    <div class="card shadow-sm">
        <!-- Card header with a secondary background -->
        <div class="card-header bg-secondary text-white">
            <h2 class="mb-0">User Profiles</h2>
        </div>
        <div class="card-body">
            <div class="table-responsive">
                <table class="table table-bordered table-striped table-hover">
                    <thead class="table-primary">
                        <tr>
                            <th>Full Name</th>
                            <th>Profile Picture</th>
                            <th>Identity Proofs</th>
                            <th>Current Status/Action</th>
                            <th>Created On</th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach (var profile in Model)
                        {
                            <tr>
                                <!-- Full Name -->
                                <td class="fw-bold align-middle">@profile.FullName</td>

                                <!-- Profile Picture -->
                                <td class="align-middle text-center">
                                    <img src="~/uploads/profile_pictures/@profile.ProfilePictureFileName"
                                         alt="Profile Picture"
                                         class="img-thumbnail"
                                         style="max-width:100px; max-height:100px;" />
                                </td>

                                <!-- Identity Proofs (Document Details) -->
                                <td class="align-middle">
                                    @if (profile.IdentityProofs != null && profile.IdentityProofs.Any())
                                    {
                                        <ul class="list-unstyled mb-0">
                                            @foreach (var proof in profile.IdentityProofs)
                                            {
                                                <li class="mb-2">
                                                    <div>
                                                        <strong class="text-primary">@proof.ProofType.Name</strong> &ndash;
                                                        <a href="~/uploads/identity_proofs/@proof.FileName" target="_blank" class="text-decoration-none">
                                                            View Document
                                                        </a>
                                                    </div>
                                                    <div>
                                                        <small class="text-muted">
                                                            Type: @proof.FileType, Size: @proof.FileSize bytes
                                                        </small>
                                                    </div>
                                                </li>
                                            }
                                        </ul>
                                    }
                                </td>

                                <!-- Current Status/Action -->
                                <td class="align-middle">
                                    @if (profile.IdentityProofs != null && profile.IdentityProofs.Any())
                                    {
                                        <ul class="list-unstyled mb-0">
                                            @foreach (var proof in profile.IdentityProofs)
                                            {
                                                <li class="mb-2">
                                                    <div class="d-flex align-items-center" style="min-height:32px;">
                                                        @{
                                                            // Determine badge class based on the verification status.
                                                            string badgeClass = "";
                                                            if (proof.VerificationStatus.Name.Equals("Pending", StringComparison.OrdinalIgnoreCase))
                                                            {
                                                                badgeClass = "badge bg-info text-dark";
                                                            }
                                                            else if (proof.VerificationStatus.Name.Equals("Verified", StringComparison.OrdinalIgnoreCase))
                                                            {
                                                                badgeClass = "badge bg-success";
                                                            }
                                                            else if (proof.VerificationStatus.Name.Equals("Rejected", StringComparison.OrdinalIgnoreCase))
                                                            {
                                                                badgeClass = "badge bg-danger";
                                                            }
                                                        }
                                                        <span class="@badgeClass" style="display:inline-block; height:32px; line-height:32px; padding: 0 10px;">
                                                            @proof.VerificationStatus.Name
                                                        </span>
                                                        @if (proof.VerificationStatus.Name.Equals("Pending", StringComparison.OrdinalIgnoreCase))
                                                        {
                                                            <a asp-action="Verify" asp-controller="UserProfile" asp-route-id="@proof.Id" class="d-flex align-items-center btn btn-sm btn-primary ms-2" style="height:32px; line-height:32px;">
                                                                Verify
                                                            </a>
                                                        }
                                                    </div>
                                                </li>
                                            }
                                        </ul>
                                    }
                                </td>

                                <!-- Created On -->
                                <td class="align-middle text-muted">@profile.CreatedOn.ToString("g")</td>
                            </tr>
                        }
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>
Verify View

Create a view named Verify.cshtml within the Views/UserProfile folder, then copy and paste the following code. This view renders the form that allows an admin to verify (approve or reject) a specific identity proof.

@model FileHandlingDemo.ViewModels.IdentityProofVerificationViewModel

@{
    ViewData["Title"] = "Verify Identity Proof";
}

<div class="container my-5">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card shadow">
                <div class="card-header bg-primary text-white">
                    <h3 class="mb-0">Verify Identity Proof</h3>
                </div>
                <div class="card-body">
                    <form asp-action="Verify" asp-controller="UserProfile" method="post">
                        <!-- Hidden field for ID -->
                        <input type="hidden" asp-for="Id" />

                        <!-- Proof Type -->
                        <div class="row mb-3 align-items-center">
                            <div class="col-sm-4 fw-bold">Proof Type:</div>
                            <div class="col-sm-8">
                                <span>@Model.ProofTypeName</span>
                            </div>
                        </div>

                        <!-- File Name with "View PDF" Option -->
                        <div class="row mb-3 align-items-center">
                            <div class="col-sm-4 fw-bold">File Name:</div>
                            <div class="col-sm-8">
                                <span>@Model.FileName</span>
                                <a href="~/uploads/identity_proofs/@Model.FileName" target="_blank" class="ms-2 text-decoration-none">View PDF</a>
                            </div>
                        </div>

                        <!-- File Type -->
                        <div class="row mb-3 align-items-center">
                            <div class="col-sm-4 fw-bold">File Type:</div>
                            <div class="col-sm-8">
                                <span>@Model.FileType</span>
                            </div>
                        </div>

                        <!-- File Size -->
                        <div class="row mb-3 align-items-center">
                            <div class="col-sm-4 fw-bold">File Size (bytes):</div>
                            <div class="col-sm-8">
                                <span>@Model.FileSize</span>
                            </div>
                        </div>

                        <!-- New Verification Status Dropdown -->
                        <div class="row mb-3 align-items-center">
                            <div class="col-sm-4 fw-bold">New Verification Status:</div>
                            <div class="col-sm-8">
                                <select asp-for="NewVerificationStatusId" class="form-select" asp-items="(SelectList)ViewBag.VerificationStatuses">
                                    <option value="">-- Select Verification Status --</option>
                                </select>
                                <span asp-validation-for="NewVerificationStatusId" class="text-danger"></span>
                            </div>
                        </div>

                        <!-- Admin Comments -->
                        <div class="row mb-3 align-items-center">
                            <div class="col-sm-4 fw-bold">Admin Comments:</div>
                            <div class="col-sm-8">
                                <textarea asp-for="AdminComments" class="form-control" rows="3"></textarea>
                                <span asp-validation-for="AdminComments" class="text-danger"></span>
                            </div>
                        </div>

                        <!-- Action Buttons -->
                        <div class="d-flex justify-content-between">
                            <a asp-action="IdentityProofs" asp-controller="Admin" class="btn btn-primary">
                                <i class="bi bi-arrow-left"></i> Back to List
                            </a>
                            <button type="submit" class="btn btn-primary">
                                <i class="bi bi-check-circle"></i> Submit Verification
                            </button>
                        </div>
                    </form>
                </div>
                <div class="card-footer text-muted text-center">
                    Please review the details carefully before submitting.
                </div>
            </div>
        </div>
    </div>
</div>
Modifying the _Layout.cshtml File:

We need to enable client-side validation and Menus for Profile Creation and verifications. So, please modify the _Layout.cshtml file as follows. It acts as the master layout that defines the common structure (header, footer, scripts, and styles) for all pages in the application.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - FileHandlingDemo</title>
    <!-- Bootstrap 5 CSS -->
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />

    <!-- Site CSS -->
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/ProductManagementApp.styles.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container-fluid">
                <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">FileHandlingDemo</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                        <!-- New Navigation Links -->
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="UserProfile" asp-action="Index">Profile List</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="UserProfile" asp-action="Create">Create Profile</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2025 - FileHandlingDemo - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>
    <!-- jQuery (for validation & older scripts, if needed) -->
    <script src="~/lib/jquery/dist/jquery.min.js"></script>

    <!-- jQuery Validation Plugin -->
    <script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>

    <!-- jQuery Unobtrusive Validation -->
    <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

    <!-- Bootstrap 5 Bundle (includes Popper) -->
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>

    <!-- Your Site JS -->
    <script src="~/js/site.js" asp-append-version="true"></script>

    <!-- Scripts Section for Razor Views -->
    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Configure Database Connection

In your appsettings.json, add a connection string pointing to the SQL Server Database, which will be used by our DbContext class. So, please modify the appsettings.json file as follows:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Server=LAPTOP-6P5NK25R\\SQLSERVER2022DEV;Database=UserProfileDB;Trusted_Connection=True;TrustServerCertificate=True;"
  }
}
Set Up DbContext, Dependency Injection and Middleware:

It serves as the application’s entry point and sets up the web host, middleware, and services needed by the app. Please modify the Program class as follows.

using FileHandlingDemo.Data;
using Microsoft.EntityFrameworkCore;

namespace FileHandlingDemo
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.
            builder.Services.AddControllersWithViews();

            // Register the ApplicationDbContext with dependency injection
            builder.Services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (!app.Environment.IsDevelopment())
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.MapControllerRoute(
                name: "default",
                pattern: "{controller=UserProfile}/{action=Index}/{id?}");

            app.Run();
        }
    }
}
Migrate and Create the Database

Open Visual Studio Package Manager Console and execute the Add-Migration Mig1 and Update-Database commands as shown in the below image:

How to Restrict Uploaded File Size and Type in an ASP.NET Core MVC Application with Examples

This will create our UserProfileDB database with the required database tables, as shown in the image below:

Restricting Uploaded File Type and Size in ASP.NET Core MVC

Now, run the application and test the functionalities, and it should work as expected.

In the next article, I will discuss How to Restrict Uploaded File Types in ASP.NET Core MVC Applications with Examples. In this article, I will try to explain how to restrict uploaded file Sizes in ASP.NET Core MVC applications with examples. And I hope you enjoy this article.

Leave a Reply

Your email address will not be published. Required fields are marked *