Master detail CRUD in Asp.net core 5 MVC using EF Core

From this tutorial you will learn how to make a Master Detail CRUD Application using ASP.NET Core 5 MVC using EF Core.

In Here , I have used advanced features of Entity framework core.

This Application is done in MVC5. 

The main objective of this application is to save the master and detail records together in a easiest and best way.

Please see below the YouTube link of this Tutorial. It is always to see as a video

then reading line by line.

Master Detail CRUD ASP.NET CORE 5 MVC


1. Start Visual Studio Twenty Nineteen. and Select  ASP.NET Core Web App 
using MVC.
2. Then Click Next to proceed further.


3. Give the Application Name as ResumeManager. as we are going to manage the resumes of applicants in this software.

4.Then Enter the Project Location as D drive slash ResumeManager. 

5. Then Click Next to proceed further.





6. After That select the Target Framework as .Net 5.0. and check Enable Razor Runtime Compilation.

7. And Click Create Button



8.Now the project is created successfully by the scaffolding task.


9.To create a Model, Right click the Models Folder. Then click New Item and
enter the model filename as Applicant.cs


11.in the Applicant Model, first we will add the required libraries in the Using Section.

12.Then add the property Named ID.  this will be Applicant id and it will became the primary key of our table.

13.Since we are going to have detail table with relation. we must have a primary key column in the Master Table. I mean in the Applicant Table.

14.Then we will have the General properties of the resume  like Name, Gender, Age. 

15. Notice that Age is having a range Validator. We are Accepting only Applicants of aged between 25 to 55 years only. this is working age. so That Make sense.

16. Then we also added two more properties named qualification and Total Experience.  Again Total Experience has a Range Validator.

17. Notice that I have specified the length for all the properties of type string.

18. Otherwise EF Core will  create a column of type nvarchar of MAX. which is not a good idea. so it is always better to  specify the length for the properties with
data type as string.

19. Now let's add the Model class to store the experience details. We will name this class as Experience. This model will became the detail table for the 
applicant table.

20. Let's add a  property named ExperienceID  ,This is the primary
key column for our experiences table. 

21. And then add the componentmodel and componentmodel.dataannotation. schema namespaces to the using section.


I request you to watch the complete Video at YouTube which explains better.

but I have copied all the required class files source and controller source.



You can copy and paste the source on when watching the video.

The ApplicantModel.cs source is below.

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ResumeManager.Models
{
    public class Applicant
    {
        [Key]
        public int Id { get; set; }


        [Required]
        [StringLength(150)]
        public string Name { get; set; } = "";

        [Required]
        [StringLength(10)]
        public string Gender { get; set; } = "";

        [Required]
        [Range(25, 55, ErrorMessage = "Currently,We Have no Positions Vacant for Your Age")]
        [DisplayName("Age in Years")]
        public int Age { get; set; }

        [Required]
        [StringLength(50)]
        public string Qualification { get; set; } = "";

        [Required]
        [Range(1, 25, ErrorMessage = "Currently,We Have no Positions Vacant for Your Experience")]
        [DisplayName("Total Experience in Years")]
        public int TotalExperience { get; set; }

        public virtual List<Experience> Experiences { get; set; } = new List<Experience>();//detail very important
        
        public string PhotoUrl { get; set; }

        [Required(ErrorMessage = "Please choose the Profile Photo")]
        [Display(Name = "Profile Photo")]
        [NotMapped]
        public IFormFile ProfilePhoto { get; set; }
    }
}


22. The Experience Model source is below.

using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;


namespace ResumeManager.Models
{
    public class Experience
    {
        public Experience()
        {
        }

        [Key]
        public int ExperienceId { get; set; }

        [ForeignKey("Applicant")]//very important
        public int ApplicantId { get; set; }
        public virtual Applicant Applicant { get; private set; } //very important 

        public string CompanyName { get; set; }
        public string Designation { get; set; }
        [Required]
        public int YearsWorked { get; set; }

    }
}


23. Resume Dbcontext source is below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using ResumeManager.Models;

namespace ResumeManager.Data
{
    public class ResumeDbContext:DbContext
    {
        public ResumeDbContext(DbContextOptions<ResumeDbContext> options):base(options)
        {
        }
        public virtual DbSet<Applicant> Applicants { get; set; }
        public virtual DbSet<Experience> Experiences { get; set; }
    }
}


24. ResumeController Source is Below.

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using ResumeManager.Data;
using ResumeManager.Models;

using System.IO;
using Microsoft.AspNetCore.Hosting;

namespace ResumeManager.Controllers
{
    public class ResumeController : Controller
    {
        private readonly ResumeDbContext _context;

        private readonly IWebHostEnvironment _webHost;




        public ResumeController(ResumeDbContext context, IWebHostEnvironment webHost)
        {
            _context = context;
            _webHost = webHost;

        }
        public IActionResult Index()
        {
            List<Applicant> applicants;
            applicants = _context.Applicants.ToList();
            return View(applicants);
        }

        [HttpGet]
        public IActionResult Create()
        {
            Applicant applicant = new Applicant();
            applicant.Experiences.Add(new Experience() { ExperienceId = 1 });
            //applicant.Experiences.Add(new Experience() { ExperienceId = 2 });
            //applicant.Experiences.Add(new Experience() { ExperienceId = 3 });
            return View(applicant);
        }


        [HttpPost]
        public IActionResult Create(Applicant applicant)
        {

            string uniqueFileName = GetUploadedFileName(applicant);
            applicant.PhotoUrl = uniqueFileName;

            _context.Add(applicant);
            _context.SaveChanges();
            return RedirectToAction("index");

        }


        private string GetUploadedFileName(Applicant applicant)
        {
            string uniqueFileName = null;

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




    }
}


25. The Javascript of Index.cshtml is below. 


@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}

<script type="text/javascript">
$(".custom-file-input").on("change", function () {
var fileName = $(this).val().split("\\").pop();
$(this).siblings(".custom-file-label").addClass("selected").html(fileName);
});



function DeleteItem(btn) {
$(btn).closest('tr').remove();
}



function AddItem(btn) {

var table = document.getElementById('ExpTable');
var rows = table.getElementsByTagName('tr');

var rowOuterHtml = rows[rows.length - 1].outerHTML;

var lastrowIdx = document.getElementById('hdnLastIndex').value;

var nextrowIdx = eval(lastrowIdx) + 1;

document.getElementById('hdnLastIndex').value = nextrowIdx;

rowOuterHtml = rowOuterHtml.replaceAll('_' + lastrowIdx + '_', '_' + nextrowIdx + '_');
rowOuterHtml = rowOuterHtml.replaceAll('[' + lastrowIdx + ']', '[' + nextrowIdx + ']');
rowOuterHtml = rowOuterHtml.replaceAll('-' + lastrowIdx, '-' + nextrowIdx);


var newRow = table.insertRow();
newRow.innerHTML = rowOuterHtml;



var btnAddID = btn.id;
var btnDeleteid = btnAddID.replaceAll('btnadd', 'btnremove');

var delbtn = document.getElementById(btnDeleteid);
delbtn.classList.add("visible");
delbtn.classList.remove("invisible");


var addbtn = document.getElementById(btnAddID);
addbtn.classList.remove("visible");
addbtn.classList.add("invisible");

}

</script>
}



Please find the YouTube video link Master Detail CRUD ASP.NET CORE 5 MVC

Please let me know if you need assistance.

All The best.

Aniz Mohammed 








Comments

  1. Pls provide a contact email address.

    ReplyDelete
  2. Excellent Tutorial, One of the Best Master Detail Crud in the internet. cheers....

    ReplyDelete
  3. Please provide complete downloadable code for beginners.

    ReplyDelete
  4. Delete functionality not working and saving data in database.

    ReplyDelete
  5. Tem uma parte do codigo que não da pra ver


    onchange="document.getElementById('PreviwPhoto').src= window.URL.createObjectURL(th..................

    ReplyDelete
  6. onchange="document.getElementById('PreviwPhoto').src= window.URL.createObjectURL(th.................. ????????????????????????????????????????????/

    ReplyDelete
  7. would you give us your source code file. thanks

    ReplyDelete
  8. plz provide full JS file code and , views code

    ReplyDelete
  9. I liked the video only issue I have is some code was already done in video and the source code was provided anywhere. Could you please share the entire project or just the create view and corresponding JS files

    ReplyDelete
  10. could you share the password of the zip file where the code is please

    ReplyDelete
    Replies
    1. Where is the zip you are talking about

      Delete
    2. Could you share the zip file please! Thanks!

      Delete
    3. Could you guys able to get zip file ? Can anyone share it ?

      Delete
    4. Please share the zip file, it would be helpful as iam working on VS Code as my OS is Ubuntu iam unable to get the functionality of Visual Studio.

      Delete
  11. ADD and Delete button cannot work properly...add button for 2nd step cannot work ...so anyone plz provide the full file of this project...

    ReplyDelete
  12. I'am working on VS code as my OS is Ubuntu can you provided me the whole project as iam unable to create the View automatically for provided action methods through scaffolding.

    ReplyDelete

Post a Comment

Popular posts from this blog