top of page

CRUD Operation With Image Upload In ASP.NET Core 5 MVC

Updated: Feb 28, 2023

Today in this article I am going to show you CURD operation with ASP.NET Core 5 MVC. We all know that Microsoft has released the version of core 5 which is now called .NET 5. So I thought why not create an article on ASP.NET core 5 MVC. It is cross platform, and some of its features are mentioned below.


For more information about features you can refer to Microsoft msdn documents. Here I am going in to perform CURD with image upload. Code.

  • C# updates.

  • F# updates.

  • Visual Basic updates.

  • System.Text.Json new features.

  • Single file apps.

  • App trimming.

  • Windows ARM64 and ARM64 intrinsics.

  • Tooling support for dump debugging

  • The runtime libraries are 80% annotated for nullable reference types

  • Performance improvements,

1. Garbage Collection (GC)

2. System.Text.Json

3. System.Text.RegularExpressions

4. Async ValueTask pooling

5. Container size optimizations

6. Many more areas


Step 1

Visual Studio 2019 16.8 or later with the ASP.NET and web development workload.

Step 2

Step 3

Start Visual Studio and select Create a new project in the Create a new project dialog.

Select ASP.NET Core Web Application > Next.


In the Configure your new project dialog, enter CURDOperationWithImageUploadCore5_Demo for Project name. It's important to use this exact name including capitalization, so each namespace matches when the code is copied. Select Create.

In the Create a new ASP.NET Core web application dialog, select,

  1. .NET Core and ASP.NET Core 5.0 in the dropdowns.

  2. ASP.NET Core Web App (Model-View-Controller).

  3. Create



Step 4

Right-click the Models folder > Add > Class. Name the file Speaker.cs.

using System;  
using System.ComponentModel.DataAnnotations;  
 
namespace CURDOperationWithImageUploadCore5_Demo.Models  
{  
 public class Speaker  
    {  
        [Key]  
 public int Id { get; set; }  
 
        [Required]  
        [StringLength(100)]  
        [Display(Name = "Name")]  
 public string SpeakerName { get; set; }  
 
        [Required]  
        [StringLength(100)]  
 public string Qualification { get; set; }  
 
        [Required]  
        [StringLength(100)]  
 public int Experience { get; set; }  
 
        [Required]  
        [DataType(DataType.Date)]  
        [Display(Name = "Date")]  
 public DateTime SpeakingDate { get; set; }  
 
        [Required]  
        [DataType(DataType.Time)]  
        [Display(Name = "Time")]  
 public DateTime SpeakingTime { get; set; }  
 
        [Required]  
        [StringLength(255)]  
 public string Venue { get; set; }  
 
        [Required]  
        [Display(Name = "Image")]  
 public string ProfilePicture { get; set; }  
    }  
}   

Step 5

From the Tools menu, select NuGet Package Manager and install the following package.

  • Microsoft.EntityFrameworkCore

  • Microsoft.EntityFrameworkCore.SqlServer

  • Microsoft.EntityFrameworkCore.Tools


Step 6

In the Solution Explorer, Create a Data folder. Create a database context class.

using CURDOperationWithImageUploadCore5_Demo.Models;  
using Microsoft.EntityFrameworkCore;  
 
namespace CURDOperationWithImageUploadCore5_Demo.Data  
{  
 public class ApplicationDbContext : DbContext  
    {  
 public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) :  
 base(options)  
        {  
 
        }  
 public DbSet<Speaker> Speakers { get; set; }  
    }  
}  


Step 7

Register the database context. Add the following using statements at the top of Startup.cs

using Microsoft.EntityFrameworkCore;  
using CURDOperationWithImageUploadCore5_Demo.Data;   

Add the following highlighted code in Startup.ConfigureServices

services.AddDbContext<ApplicationDbContext>(options =>options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));  


Step 8

Add a database connection string. Add a connection string to the appsettings.json file

"ConnectionStrings": {  
"DefaultConnection": "Server=(localdb)
\\mssqllocaldb;
Database=SpeakerDB;
Trusted_Connection=True;
MultipleActiveResultSets=true" 
}   

Step 9

Use the scaffolding tool to produce Create, Read, Update, and Delete (CRUD) pages for the movie model. In Solution Explorer, right-click the Controllers folder > Add > New Scaffolded Item.

In the Add Scaffold dialog, select MVC Controller with views, using Entity Framework > Add.

Complete the Add Controller dialog,

  • Model class: Speaker (Speaker.Models)

  • Data context class: ApplicationDbContext (ApplicationDbContext.Data)

  • Views: Keep the default of each option checked

  • Controller name: Keep the default SpeakersController

  • Select Add


Visual Studio creates

  • A movies controller (Controllers/SpeakerController.cs)

  • Razor view files for Create, Delete, Details, Edit, and Index pages (Views/Speakers/*.cshtml)


Complete Controller Code

using CURDOperationWithImageUploadCore5_Demo.Data;  
using CURDOperationWithImageUploadCore5_Demo.Models;  
using CURDOperationWithImageUploadCore5_Demo.ViewModels;  
using Microsoft.AspNetCore.Hosting;  
using Microsoft.AspNetCore.Mvc;  
using Microsoft.EntityFrameworkCore;  
using System;  
using System.IO;  
using System.Linq;  
using System.Threading.Tasks;  
 
namespace CURDOperationWithImageUploadCore5_Demo.Controllers  
{  
 public class SpeakersController : Controller  
    {  
 private readonly ApplicationDbContext db;  
 private readonly IWebHostEnvironment webHostEnvironment;  
 public SpeakersController(ApplicationDbContext context, IWebHostEnvironment hostEnvironment)  
        {  
            db = context;  
            webHostEnvironment = hostEnvironment;  
        }  
 
 public async Task<IActionResult> Index()  
        {  
 return View(await db.Speakers.ToListAsync());  
        }  
 
 public async Task<IActionResult> Details(int? id)  
        {  
 if (id == null)  
            {  
 return NotFound();  
            }  
 
            var speaker = await db.Speakers  
                .FirstOrDefaultAsync(m => m.Id == id);  
 
            var speakerViewModel = new SpeakerViewModel()  
            {  
                Id = speaker.Id,  
                SpeakerName = speaker.SpeakerName,  
                Qualification = speaker.Qualification,  
                Experience = speaker.Experience,  
                SpeakingDate = speaker.SpeakingDate,  
                SpeakingTime = speaker.SpeakingTime,  
                Venue = speaker.Venue,  
                ExistingImage = speaker.ProfilePicture  
            };  
 
 if (speaker == null)  
            {  
 return NotFound();  
            }  
 
 return View(speaker);  
        }  
 
 public IActionResult Create()  
        {  
 return View();  
        }  
 
        [HttpPost]  
        [ValidateAntiForgeryToken]  
 public async Task<IActionResult> Create(SpeakerViewModel model)  
        {  
 if (ModelState.IsValid)  
            {  
 string uniqueFileName = ProcessUploadedFile(model);  
                Speaker speaker = new Speaker  
                {  
                    SpeakerName = model.SpeakerName,  
                    Qualification = model.Qualification,  
                    Experience = model.Experience,  
                    SpeakingDate = model.SpeakingDate,  
                    SpeakingTime = model.SpeakingTime,  
                    Venue = model.Venue,  
                    ProfilePicture = uniqueFileName  
                };  
 
                db.Add(speaker);  
                await db.SaveChangesAsync();  
 return RedirectToAction(nameof(Index));  
            }  
 return View(model);  
        }  
 
 public async Task<IActionResult> Edit(int? id)  
        {  
 if (id == null)  
            {  
 return NotFound();  
            }  
 
            var speaker = await db.Speakers.FindAsync(id);  
            var speakerViewModel = new SpeakerViewModel()  
            {  
                Id = speaker.Id,  
                SpeakerName = speaker.SpeakerName,  
                Qualification = speaker.Qualification,  
                Experience = speaker.Experience,  
                SpeakingDate = speaker.SpeakingDate,  
                SpeakingTime = speaker.SpeakingTime,  
                Venue = speaker.Venue,  
                ExistingImage = speaker.ProfilePicture  
            };  
 
 if (speaker == null)  
            {  
 return NotFound();  
            }  
 return View(speakerViewModel);  
        }  
 
        [HttpPost]  
        [ValidateAntiForgeryToken]  
 public async Task<IActionResult> Edit(int id, SpeakerViewModel model)  
        {  
 if (ModelState.IsValid)  
            {  
                var speaker = await db.Speakers.FindAsync(model.Id);  
                speaker.SpeakerName = model.SpeakerName;  
                speaker.Qualification = model.Qualification;  
                speaker.Experience = model.Experience;  
                speaker.SpeakingDate = model.SpeakingDate;  
                speaker.SpeakingTime = model.SpeakingTime;  
                speaker.Venue = model.Venue;  
 
 if (model.SpeakerPicture != null)  
                {  
 if (model.ExistingImage != null)  
                    {  
 string filePath = Path.Combine(webHostEnvironment.WebRootPath, "Uploads", model.ExistingImage);  
                        System.IO.File.Delete(filePath);  
                    }  
 
                    speaker.ProfilePicture = ProcessUploadedFile(model);  
                }  
                db.Update(speaker);  
                await db.SaveChangesAsync();  
 return RedirectToAction(nameof(Index));  
            }  
 return View();  
        }  
 
 public async Task<IActionResult> Delete(int? id)  
        {  
 if (id == null)  
            {  
 return NotFound();  
            }  
 
            var speaker = await db.Speakers  
                .FirstOrDefaultAsync(m => m.Id == id);  
 
            var speakerViewModel = new SpeakerViewModel()  
            {  
                Id = speaker.Id,  
                SpeakerName = speaker.SpeakerName,  
                Qualification = speaker.Qualification,  
                Experience = speaker.Experience,  
                SpeakingDate = speaker.SpeakingDate,  
                SpeakingTime = speaker.SpeakingTime,  
                Venue = speaker.Venue,  
                ExistingImage = speaker.ProfilePicture  
            };  
 if (speaker == null)  
            {  
 return NotFound();  
            }  
 
 return View(speakerViewModel);  
        }  
 
        [HttpPost, ActionName("Delete")]  
        [ValidateAntiForgeryToken]  
 public async Task<IActionResult> DeleteConfirmed(int id)  
        {  
            var speaker = await db.Speakers.FindAsync(id);  
            var CurrentImage = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot\\images", speaker.ProfilePicture);  
            db.Speakers.Remove(speaker);  
 if (await db.SaveChangesAsync() > 0)  
            {  
 if (System.IO.File.Exists(CurrentImage))  
                {  
                    System.IO.File.Delete(CurrentImage);  
                }  
            }  
 return RedirectToAction(nameof(Index));  
        }  
 
 private bool SpeakerExists(int id)  
        {  
 return db.Speakers.Any(e => e.Id == id);  
        }  
 
 private string ProcessUploadedFile(SpeakerViewModel model)  
        {  
 string uniqueFileName = null;  
 
 if (model.SpeakerPicture != null)  
            {  
 string uploadsFolder = Path.Combine(webHostEnvironment.WebRootPath, "Uploads");  
                uniqueFileName = Guid.NewGuid().ToString() + "_" + model.SpeakerPicture.FileName;  
 string filePath = Path.Combine(uploadsFolder, uniqueFileName);  
 using (var fileStream = new FileStream(filePath, FileMode.Create))  
                {  
                    model.SpeakerPicture.CopyTo(fileStream);  
                }  
            }  
 
 return uniqueFileName;  
        }  
    }  
}   


Step 10

Initial migration. Use the EF Core Migrations feature to create the database. Migrations is a set of tools that let you create and update a database to match your data model.

From the Tools menu, select NuGet Package Manager > Package Manager Console (PMC).

  1. Add-Migration InitialModel

  2. Update-Database


Step 11

Create ViewModels folder for UploadImageViewModel,EditImageViewModel and SpeakerViewModel.

UploadImageViewModel

using Microsoft.AspNetCore.Http;  
using System.ComponentModel.DataAnnotations;  
 
namespace CURDOperationWithImageUploadCore5_Demo.ViewModels  
{  
 public class UploadImageViewModel  
    {  
        [Required]  
        [Display(Name = "Image")]  
 public IFormFile SpeakerPicture { get; set; }  
    }  
}  


EditImageViewModel

namespace CURDOperationWithImageUploadCore5_Demo.ViewModels  
{  
 public class EditImageViewModel : UploadImageViewModel  
    {  
 public int Id { get; set; }  
 public string ExistingImage { get; set; }  
    }  
}  


SpeakerViewModel



using System;  
using System.ComponentModel.DataAnnotations;  
 
namespace CURDOperationWithImageUploadCore5_Demo.ViewModels  
{  
 public class SpeakerViewModel : EditImageViewModel  
    {  
        [Required]  
        [Display(Name = "Name")]  
 public string SpeakerName { get; set; }  
 
        [Required]  
 public string Qualification { get; set; }  
 
        [Required]  
 public int Experience { get; set; }  
 
        [Required]  
        [DataType(DataType.Date)]  
        [Display(Name = "Date")]  
 public DateTime SpeakingDate { get; set; }  
 
        [Required]  
        [DataType(DataType.Time)]  
        [Display(Name = "Time")]  
 public DateTime SpeakingTime { get; set; }  
 
        [Required]  
 public string Venue { get; set; }  
    }  
}  


Step 12

Create Uploads folder in wwwroot folder to upload images.

Step 13

Built and Run your project Ctrl+F5


Index List of Speaker


Speaker Details

New Speaker


Edit Speaker Details

Delete Speaker


Conclusion

This article was about create, details, edit and delete with image file upload. I hope enjoyed the article.


Keep Reading Keep Learning!


Source: C# Corner - By Farhan Ahmed


The Tech Platform


1 comment

1 Comment


Guest
Mar 16

When I click the Edit button, the following error appears: InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'CURDOperationWithImageUploadCore5_Demo.ViewModels.SpeakerViewModel', but this ViewDataDictionary instance requires a model item of type 'CURDOperationWithImageUploadCore5_Demo.Models.Speake

Like
bottom of page