Image cropping using Jcrop in ASP.NET MVC Application

What is Image cropping?

  • Image cropping refer to removal of some part of image
  • Uses to improve framing and size
  • Applied in photograph to resize image

Application overview
In this project, I will show image cropping of an employee phot when employee information saved and modified. Full crud operation applied in the application with image cropping.
Let’s have a look on the implementation of the project.

Tools and Technology used

I used following tools and technology to develop the project –

  1. Visual Studio 2015
  2. Visual C#
  3. ASP.NET MVC
  4. Entity Framework 5
  5. Razor view engine
  6. JCrop

Step 1: Create a ASP.net MVC Project
File -> New project and select the project template Visual C# -> ASP.NET Web Application (.NET Framework) -> Console application (.NET Core).

0108_01

Select MVC as a Template as ASP.NET Template and click OK

0108_02

Step 2: Change or Add Connection String
Change or Add connection string in Web.config as follows

  
    
  
  

Step 3: Install JCrop Nuget Package
Go to Tools -> NuGet Package Manager -> Manages NuGet Package Manager for the solution -> Search Jcrop and install jquery.jcrop.js

0108_02_B

Step 4: Create model class

Create model class “Employee” as follows.

Employee Class

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

namespace JCropMVC.Models
{
    public class Employee
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [Display(Name = "Full Name")]
        [Required(ErrorMessage = "Name cannot be empty")]
        public string Name { get; set; }

        [Display(Name = "Father Name")]
        public string FatherName { get; set; }

        [Display(Name = "Designation")]
        public string Designation { get; set; }

        [Display(Name = "Mobile No")]
        public string Mobile { get; set; }

        [DataType(DataType.EmailAddress)]
        [Display(Name = "Email")]
        public string Email { get; set; }

        [Display(Name = "Image URL")]
        public string PhotoURL { get; set; }
    }
}

Step 5: Modify Context class
Modify ApplicationDbContext in IdentityModel Class

    public class ApplicationDbContext : IdentityDbContext
    {
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {
        }

        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }

        public DbSet Employees { get; set; }
    }

Step 6: Create Controller and Views
Create Employees Controller and Views
Click Right button on Controller Folder->Add Controller. Now choose scaffolding template as MVC Controllers with views using Entity Framework and then Click Add.

0108_03

Now select Model class as Employee and Data Context Class as ApplicationDbContext as follows. Then click OK.

0108_04

Step 7: Modify the controller
Modify EmployeesController as follows. Here method ProcessImage(string croppedImage) is used to process and save image. An extra parameter added for Create and Edit action.

using System;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using JCropMVC.Models;
using System.IO;

namespace JCropMVC.Controllers
{
    public class EmployeesController : Controller
    {
        private ApplicationDbContext db = new ApplicationDbContext();

        // GET: Employees
        public ActionResult Index()
        {
            return View(db.Employees.ToList());
        }

        // GET: Employees/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Employee employee = db.Employees.Find(id);
            if (employee == null)
            {
                return HttpNotFound();
            }
            return View(employee);
        }

        // GET: Employees/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Employees/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,Name,FatherName,Designation,Mobile,Email,PhotoURL")] Employee employee, string avatarCropped)
        {
            string filePath = ProcessImage(avatarCropped);
            employee.PhotoURL = filePath;

            if (ModelState.IsValid)
            {
                db.Employees.Add(employee);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(employee);
        }

        /// 
        /// Process image and save in predefined path
        /// 
        /// 
        /// 
        private string ProcessImage(string croppedImage)
        {
            string filePath = String.Empty;
            try
            {
                string base64 = croppedImage;
                byte[] bytes = Convert.FromBase64String(base64.Split(',')[1]);
                filePath = "/Images/Photo/Emp-" + Guid.NewGuid() + ".png";
                using (FileStream stream = new FileStream(Server.MapPath(filePath), FileMode.Create))
                {
                    stream.Write(bytes, 0, bytes.Length);
                    stream.Flush();
                }
            }
            catch (Exception ex)
            {
                string st = ex.Message;
            }

            return filePath;
        }

        // GET: Employees/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Employee employee = db.Employees.Find(id);
            if (employee == null)
            {
                return HttpNotFound();
            }
            return View(employee);
        }

        // POST: Employees/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,Name,FatherName,Designation,Mobile,Email,PhotoURL")] Employee employee, string avatarCropped)
        {
            string filePath = ProcessImage(avatarCropped);
            employee.PhotoURL = filePath;

            if (ModelState.IsValid)
            {
                db.Entry(employee).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(employee);
        }

        //[Authorize(Users ="sumon")]
        // GET: Employees/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Employee employee = db.Employees.Find(id);
            if (employee == null)
            {
                return HttpNotFound();
            }
            return View(employee);
        }

        // POST: Employees/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Employee employee = db.Employees.Find(id);
            db.Employees.Remove(employee);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

Step 8: Modify the views for Employee

Create.cshtml

@model JCropMVC.Models.Employee

@{
    ViewBag.Title = "Create";
}



@using (Html.BeginForm("Create", "Employees", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()

    
@Html.ValidationSummary(true)
@Html.LabelFor(model => model.Name, new { @class = "" }) @Html.TextBoxFor(model => model.Name, new { @class = "form-control", placeholder = "Enter employee full name...", type = "text" }) @Html.ValidationMessageFor(model => model.Name)
@Html.LabelFor(model => model.FatherName, new { @class = "" }) @Html.TextBoxFor(model => model.FatherName, new { @class = "form-control", placeholder = "Enter father name...", type = "text" }) @Html.ValidationMessageFor(model => model.FatherName)
@Html.LabelFor(model => model.Designation, new { @class = "" }) @Html.TextBoxFor(model => model.Designation, new { @class = "form-control", placeholder = "Enter designation name...", type = "text" }) @Html.ValidationMessageFor(model => model.Designation)
@Html.LabelFor(model => model.Mobile, new { @class = "" }) @Html.TextBoxFor(model => model.Mobile, new { @class = "form-control", placeholder = "Enter mobile number...", type = "text" }) @Html.ValidationMessageFor(model => model.Mobile)
@Html.LabelFor(model => model.Email, new { @class = "" }) @Html.TextBoxFor(model => model.Email, new { @class = "form-control", placeholder = "Enter email address...", type = "text" }) @Html.ValidationMessageFor(model => model.Email)
@Html.LabelFor(model => model.PhotoURL, new { @class = "" })
Width:   Height: Crop Image
Employee Image

}
@Html.ActionLink("Back to List", "Index")
@section Scripts { @Scripts.Render("~/bundles/jqueryval") }

Edit.cshtml

@model JCropMVC.Models.Employee

@{
    ViewBag.Title = "Edit";
}

Edit

@using (Html.BeginForm()) { @Html.AntiForgeryToken() @*
*@

Employee


@Html.ValidationSummary(true, "", new { @class = "text-danger" }) @Html.HiddenFor(model => model.Id)
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "" }) @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.FatherName, htmlAttributes: new { @class = "" }) @Html.EditorFor(model => model.FatherName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.FatherName, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.Designation, htmlAttributes: new { @class = "" }) @Html.EditorFor(model => model.Designation, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Designation, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.Mobile, htmlAttributes: new { @class = "" }) @Html.EditorFor(model => model.Mobile, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Mobile, "", new { @class = "text-danger" })
@Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "" }) @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
@*
@Html.LabelFor(model => model.PhotoURL, htmlAttributes: new { @class = "" })
@Html.EditorFor(model => model.PhotoURL, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.PhotoURL, "", new { @class = "text-danger" })
*@
@Html.LabelFor(model => model.PhotoURL, new { @class = "" })
Width:   Height: Crop Image
Employee Image

@*
*@ }
@Html.ActionLink("Back to List", "Index")
@section Scripts { @Scripts.Render("~/bundles/jqueryval") }

Index.cshtml

@model IEnumerable

@{
    ViewBag.Title = "Index";
}

Index

@Html.ActionLink("Create New", "Create")

@foreach (var item in Model) { }
@Html.DisplayNameFor(model => model.Name) @Html.DisplayNameFor(model => model.FatherName) @Html.DisplayNameFor(model => model.Designation) @Html.DisplayNameFor(model => model.Mobile) @Html.DisplayNameFor(model => model.Email) @Html.DisplayNameFor(model => model.PhotoURL)
@Html.DisplayFor(modelItem => item.Name) @Html.DisplayFor(modelItem => item.FatherName) @Html.DisplayFor(modelItem => item.Designation) @Html.DisplayFor(modelItem => item.Mobile) @Html.DisplayFor(modelItem => item.Email) @**@ @*@Html.DisplayFor(modelItem => item.PhotoURL)*@ @Html.ActionLink("Edit", "Edit", new { id=item.Id }) | @Html.ActionLink("Details", "Details", new { id=item.Id }) | @Html.ActionLink("Delete", "Delete", new { id=item.Id })

Delete.cshtml

@model JCropMVC.Models.Employee

@{
    ViewBag.Title = "Delete";
}

Delete

Are you sure you want to delete this?

Employee


@Html.DisplayNameFor(model => model.Name)
@Html.DisplayFor(model => model.Name)
@Html.DisplayNameFor(model => model.FatherName)
@Html.DisplayFor(model => model.FatherName)
@Html.DisplayNameFor(model => model.Designation)
@Html.DisplayFor(model => model.Designation)
@Html.DisplayNameFor(model => model.Mobile)
@Html.DisplayFor(model => model.Mobile)
@Html.DisplayNameFor(model => model.Email)
@Html.DisplayFor(model => model.Email)
@Html.DisplayNameFor(model => model.PhotoURL)
@Html.DisplayFor(model => model.PhotoURL)
@using (Html.BeginForm()) { @Html.AntiForgeryToken()
| @Html.ActionLink("Back to List", "Index")
}

Step 9: Add image folders
Add Image folders and sub folders (Deafult and Photo) as follows. Add blank photo in the Default folder to show blank photo for the employee.

0108_05

Step 10: Add Employee link
Add Employee link in the nav bar of _Layout page as follows.

                

Step 11: Run the application
Now run the application. Click Employee link in the nav bar. You can View, add, modify and delete employee information. If you go to the create or edit page, you have an option to upload photo and have option to crop the image and then save the image with employee information. Yes! You are done. Let’s cheers!

0108_06

Building a simple application using ASP.NET Core 1.0

What is .NET Core?

  • .NET Core is a general-purpose development platform
  • Maintained by Microsoft and the .NET community on GitHub
  • Its work in cross-platform, supporting Windows, macOS and Linux
  • Can be used in device, cloud, and embedded/IoT scenarios.
  • First release on 27 June, 2016

Application overview
HRM Core an application which I will develop here. User can view, add, edit and delete Employee information with his department and designation. This application will be developed by asp.net core.
Let’s come to the implementation of the project.

Tools and Technology used
I used following tools and technology to develop the project –

  1. Visual Studio 2015 Update 3
  2. Visual C#
  3. ASP.NET MVC
  4. Entity Framework core 1.0
  5. Razor view engine
  6. JQuery

Step 1: Create a ASP.net MVC Project
File -> New project and select the project template C# -> .NET Core -> Console application (.NET Core).

0107_01

Select Web Application as a Template, change authentication to individual user account and click OK
0107_02

Step 2: Change or Add Connection String
Change or Add connection string in appsettings.json as follows


{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=HRMCoreDB;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

Step 3: Create model classes

Create three model classes Dept, Designation and Employee as follows.

Dept Class

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;

namespace HRMCore.Models
{
    public class Dept
    {
        public Dept()
        {
            ActionDate = DateTime.Now;
        }

        //[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int DeptId { get; set; }

        [Display(Name = "Dept")]
        public string Name { get; set; }

        public string Location { get; set; }

        public virtual List Employees { get; set; }
        public DateTime ActionDate { get; set; }
    }
}

Designation Class


using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;

namespace HRMCore.Models
{
    public class Designation
    {
        public Designation()
        {
            ActionDate = DateTime.Now;
        }
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        [Display(Name = "Designation")]
        public string Name { get; set; }
        public virtual List Employees { get; set; }
        public DateTime ActionDate { get; set; }
    }
}

Employee Class

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;

namespace HRMCore.Models
{
    public class Employee
    {
        public Employee()
        {
            ActionDate = DateTime.Now;
        }

        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [Display(Name = "Employee Code")]
        public string EmpCode { get; set; }

        [Display(Name = "Full Name")]
        public string FullName { get; set; }

        [Display(Name = "Nick Name")]
        public string NickName { get; set; }

        [Display(Name = "Designation")]
        public int DesignationId { get; set; }

        [ForeignKey("DesignationId")]
        public virtual Designation Designation { get; set; }

        [Display(Name = "Department")]
        public int DeptId { get; set; }

        [ForeignKey("DeptId")]
        public virtual Dept Dept { get; set; }

        public string Phone { get; set; }
        public string Email { get; set; }
        public string Address { get; set; }
        public DateTime ActionDate { get; set; }
    }
}

Step 4: Modify Context class
Modify ApplicationDbContext in Data folder. Add DbSet for Dept, Designation and Employee model

using Microsoft.AspNet.Identity.EntityFramework;
using System.Data.Entity;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using HRMCore.Models;

namespace HRMCore.Data
{
    public class ApplicationDbContext : IdentityDbContext
    {
        public ApplicationDbContext(DbContextOptions options)
            : base(options)
        {
        }

        public DbSet Depts { get; set; }
        public DbSet Designations { get; set; }
        public DbSet Employees { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
            // Customize the ASP.NET Identity model and override the defaults if needed.
            // For example, you can rename the ASP.NET Identity table names and more.
            // Add your customizations after calling base.OnModelCreating(builder);
        }
    }
}


Step 5: Create Controller and Views

Create Depts Controller and Views
Click Right button on Controller Folder->Add Controller. Now choose scaffolding template as MVC Controllers with views using Entity Framework and then Click Add.

0107_02_b

Now select Model class as Dept and Data Context Class as ApplicationDbContext as follows. Then click OK.

0107_03

Create Employees Controller and Views
Click Right button on Controller Folder->Add Controller. Now choose scaffolding template as MVC Controllers with views using Entity Framework and then Click Add as before.

Then select Model class as Employee and Data Context Class as ApplicationDbContext as follows. Then click OK.

0107_04


Step 6: Modify the controller

Modify EmployeeController as follows.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using HRMCore.Data;
using HRMCore.Models;

namespace HRMCore.Controllers
{
    public class EmployeesController : Controller
    {
        private readonly ApplicationDbContext _context;

        public EmployeesController(ApplicationDbContext context)
        {
            _context = context;    
        }

        // GET: Employees
        public async Task Index()
        {
            var applicationDbContext = _context.Employees.Include(e => e.Dept).Include(e => e.Designation);
            return View(await applicationDbContext.ToListAsync());
        }

        // GET: Employees/Details/5
        public async Task Details(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var employee = await _context.Employees.SingleOrDefaultAsync(m => m.Id == id);
            if (employee == null)
            {
                return NotFound();
            }

            return View(employee);
        }

        // GET: Employees/Create
        public IActionResult Create()
        {
            ViewData["DeptId"] = new SelectList(_context.Depts, "DeptId", "Name");
            ViewData["DesignationId"] = new SelectList(_context.Designations, "Id", "Name");
            return View();
        }

        // POST: Employees/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task Create([Bind("Id,ActionDate,Address,DeptId,DesignationId,Email,EmpCode,FullName,NickName,Phone")] Employee employee)
        {
            if (ModelState.IsValid)
            {
                _context.Add(employee);
                await _context.SaveChangesAsync();
                return RedirectToAction("Index");
            }
            ViewData["DeptId"] = new SelectList(_context.Depts, "DeptId", "Name", employee.DeptId);
            ViewData["DesignationId"] = new SelectList(_context.Designations, "Id", "Name", employee.DesignationId);
            return View(employee);
        }

        // GET: Employees/Edit/5
        public async Task Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var employee = await _context.Employees.SingleOrDefaultAsync(m => m.Id == id);
            if (employee == null)
            {
                return NotFound();
            }
            ViewData["DeptId"] = new SelectList(_context.Depts, "DeptId", "Name", employee.DeptId);
            ViewData["DesignationId"] = new SelectList(_context.Designations, "Id", "Name", employee.DesignationId);
            return View(employee);
        }

        // POST: Employees/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task Edit(int id, [Bind("Id,ActionDate,Address,DeptId,DesignationId,Email,EmpCode,FullName,NickName,Phone")] Employee employee)
        {
            if (id != employee.Id)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(employee);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!EmployeeExists(employee.Id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction("Index");
            }
            ViewData["DeptId"] = new SelectList(_context.Depts, "DeptId", "Name", employee.DeptId);
            ViewData["DesignationId"] = new SelectList(_context.Designations, "Id", "Name", employee.DesignationId);
            return View(employee);
        }

        // GET: Employees/Delete/5
        public async Task Delete(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var employee = await _context.Employees.SingleOrDefaultAsync(m => m.Id == id);
            if (employee == null)
            {
                return NotFound();
            }

            return View(employee);
        }

        // POST: Employees/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task DeleteConfirmed(int id)
        {
            var employee = await _context.Employees.SingleOrDefaultAsync(m => m.Id == id);
            _context.Employees.Remove(employee);
            await _context.SaveChangesAsync();
            return RedirectToAction("Index");
        }

        private bool EmployeeExists(int id)
        {
            return _context.Employees.Any(e => e.Id == id);
        }
    }
}

Step 7: Modify the view
Modify the views if required.

Step 8: Add Seed method
Add a seed class name DataSeeder in model class as follows.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
//using Microsoft.AspNet.Builder;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using HRMCore.Data;
//using System.Data

namespace HRMCore.Models
{

    public static class DataSeeder
    {
        // TODO: Move this code when seed data is implemented in EF 7

        /// 
        /// This is a workaround for missing seed data functionality in EF 7.0-rc1
        /// More info: https://github.com/aspnet/EntityFramework/issues/629
        /// 
        /// 
        /// An instance that provides the mechanisms to get instance of the database context.
        /// 
        public static void SeedData(this IApplicationBuilder app)
        {
            var db = app.ApplicationServices.GetService();

            // TODO: Add seed logic here


            var objSE = new Designation { Name = "Software Engineer" };
            var objSSE = new Designation { Name = "Senior Engineer" };
            var objSA = new Designation { Name = "Software Archiect" };
            var objBA = new Designation { Name = "Business Analyst" };
            var objOfficer = new Designation { Name = "Officer" };
            var objSrOfficer = new Designation { Name = "Sr. Officer" };
            var objAssMgr = new Designation { Name = "Asst. Manager" };

            var objSSD = new Dept { Name = "Software Development" };
            var objIMP = new Dept { Name = "Software Implementation" };
            var objFin = new Dept { Name = "Finance & Administration" };
            var objMkt = new Dept { Name = "Sells & Marketing" };



            var lstEmployees = new List()
            {
                new Employee(){EmpCode = "L0001", FullName = "Tariqul Islam", NickName = "Shakil",
                    Designation = objSE, Dept = objSSD, Phone = "01715333333", Email ="demo@gmail.com"  },

                new Employee(){EmpCode = "L0002", FullName = "Enamul Haque", NickName = "Rony",
                    Designation = objSSE, Dept = objIMP, Phone = "01715333332", Email ="deom@gmail.com"  },

                new Employee(){EmpCode = "L0003", FullName = "Mallik Arif Ahsan", NickName = "Arif",
                    Designation = objAssMgr, Dept = objFin, Phone = "01715333332", Email ="deom@gmail.com"  },

                new Employee(){EmpCode = "L0004", FullName = "Jafrin Islam", NickName = "Sinthi",
                    Designation = objSSE, Dept = objSSD, Phone = "01715333334", Email ="demo@gmail.com"  },

                new Employee(){EmpCode = "L0005", FullName = "Md. Mahedee Hasan", NickName = "Mahedee",
                    Designation = objSSE, Dept = objSSD, Phone = "01715333334", Email ="demo@gmail.com"  },

            };


            List lstDept = new List {
                     new Dept { Name = "Supply Chain" },
                     new Dept { Name = "Software Innovation" }
                };

            List lstDesignation = new List
            {
                    new Designation { Name = "Executive" },
                    new Designation { Name = "Senior Executive" },
                    new Designation { Name = "Manager" },
                    new Designation { Name = "Deputy Manager" },
                    new Designation { Name = "Project Manager" }
            };

            if (db.Depts.ToList().Count <= 0)
                db.AddRange(lstDept);

            if (db.Designations.ToList().Count <= 0)
                db.AddRange(lstDesignation);

            if (db.Employees.ToList().Count <= 0)
                db.Employees.AddRange(lstEmployees);

            db.SaveChanges();
        }
    }
}
[/csharp]

Step 9: Add SeedData Method 
Add SeedData method in Startup class as follows.

[csharp]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using HRMCore.Data;
using HRMCore.Models;
using HRMCore.Services;

namespace HRMCore
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

            if (env.IsDevelopment())
            {
                // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
                builder.AddUserSecrets();
            }

            builder.AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddDbContext(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity()
                .AddEntityFrameworkStores()
                .AddDefaultTokenProviders();

            services.AddMvc();

            // Add application services.
            services.AddTransient();
            services.AddTransient();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
                app.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            app.UseIdentity();
            app.SeedData();

            // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

Step 9: Add Migration
Go to Tools -> NuGet Package Manager -> Package Manager Console
Run the following command in the package manager console.
PM> Add-Migration addmodel
Then run the following command in the package manager console.
PM> Update-Database -Verbose

Step 10: Add Links in Layout Page
Add Dep and Employee link as follows.

  • Home
  • About
  • Contact
  • Dept
  • Employee
  • Now run the application. Click Dept or Employee link in the nav bar. You can View, add, modify and delete employee information as well as department information. Thanks for your patience.

    0107_05

    Microsoft Student Partner (MSP) Capacity Build up Training (Session 04)

    Microsoft Student Partner (MSP) Capacity Build up Training (Session 04)
    Course Title: Object Oriented Programming with C#
    Venue: East West University, Dhaka, Bangladesh
    Date: 23 July, 2016
    Speaker / Trainer: Md. Mahedee Hasan,
    Microsoft MVP, Visual Studio and Development Technologies
    Software Architect, Leadsoft Bangladesh Limited
    Trainer, Leads Technology Limited

    Microsoft Student Partner (MSP) Capacity Build up Training (Session 03)

    Microsoft Student Partner (MSP) Capacity Build up Training (Session 03)
    Course Title: Object Oriented Programming with C#
    Venue: East West University, Dhaka, Bangladesh
    Date: 25 June, 2016
    Speaker / Trainer: Md. Mahedee Hasan,
    Microsoft MVP, Visual Studio and Development Technologies
    Software Architect, Leadsoft Bangladesh Limited
    Trainer, Leads Technology Limited.

    Microsoft Student Partner (MSP) Capacity Build up Training (Session 02)

    Microsoft Student Partner (MSP) Capacity Build up Training (Session 02)
    Course Title: Object Oriented Programming with C#
    Venue: East West University, Dhaka, Bangladesh
    Date: 11 June, 2016
    Speaker / Trainer: Md. Mahedee Hasan,
    Microsoft MVP, Visual Studio and Development Technologies
    Software Architect, Leadsoft Bangladesh Limited

    Microsoft Student Partner (MSP) Capacity Build up Training (Session 01)


    Microsoft Student Partner (MSP) Capacity Build up Training (Session 01)
    Course Title: Object Oriented Programming with C#
    Venue: East West University, Dhaka, Bangladesh
    Date: 28 May, 2016
    Speaker / Trainer: Md. Mahedee Hasan,
    Microsoft MVP, Visual Studio and Development Technologies
    Software Architect, Leadsoft Bangladesh Limited
    Trainer, Leads Technology Limited

    Object Oriented Programming with C# and ASP.NET MVC 5 (Batch 05)

    Training Title: Object Oriented Programming with C# and ASP.NET MVC 05
    Batch: 05
    Duration: 104 hours
    Venue: Leads Technology Limited.
    Trainer: Md. Mahedee Hasan
    Microsoft MVP, Visual Studio and Development Technologies.
    Software Architect, Leadsoft Bangladesh Limited

    CRUD and search operation in ASP.NET MVC application using partial view

    What is Partial View in ASP.NET MVC?

  • Partial view is a view which is rendered in another view
  • Partial view render portion of pages
  • Using partial view, you can reuse portion of page
  • Partial view is similar to a normal view with .cshtml


  • Project overview

    Here I create an application to keep basic employee information. View, add, update and delete option of an employee is in the application. I used partial view to show employee information in grid. Here I showed how do you run CRUD operation using partial view in most manageable way.
    Let’s come to the implementation of the project.

    Tools and Technology used
    I used following tools and technology to develop the project –

    1. Visual Studio 2013
    2. Visual C#
    3. ASP.NET MVC 5
    4. Entity Framework 6
    5. Razor view engine
    6. JQuery

    Step 1: Create a ASP.net MVC Project
    From Visual studio 2013, choose File->Project -> ASP.NET Web application as below

    0106_01

    Select MVC Template and click OK

    0106_02


    Step 2: Change or Add Connection String

    Change or Add connection string in Web.config as follows

    
    

    Step 3: Create model classes

    Create three model classes Dept, Designation and Employee as follows.

    Dept Class

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace Web.HRM.Models
    {
        public class Dept
        {
            public Dept()
            {
                ActionDate = DateTime.Now;
            }
    
            [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
            public int Id { get; set; }
    
            [Display(Name = "Dept")]
            public string Name { get; set; }
    
            public virtual List Employees { get; set; }
            public DateTime ActionDate { get; set; }
        }
    }
    
    

    Designation Class

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace Web.HRM.Models
    {
        public class Designation
        {
            public Designation()
            {
                ActionDate = DateTime.Now;
            }
            [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
            public int Id { get; set; }
            [Display(Name = "Designation")]
            public string Name { get; set; }
            public virtual List Employees { get; set; }
            public DateTime ActionDate { get; set; }
    
        }
    }
    

    Employee Class

    using System;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace Web.HRM.Models
    {
        public class Employee
        {
            public Employee()
            {
                ActionDate = DateTime.Now;
            }
    
            [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
            public int Id { get; set; }
    
            [Display(Name = "Employee Code")]
            public string EmpCode { get; set; }
    
            [Display(Name = "Full Name")]
            public string FullName { get; set; }
    
            [Display(Name = "Nick Name")]
            public string NickName { get; set; }
    
            [Display(Name = "Designation")]
            public int DesignationId { get; set; }
    
            [ForeignKey("DesignationId")]
            public virtual Designation Designation { get; set; }
    
            [Display(Name = "Department")]
            public int DeptId { get; set; }
    
            [ForeignKey("DeptId")]
            public virtual Dept Dept { get; set; }
    
            public string Phone { get; set; }
            public string Email { get; set; }
            public string Address { get; set; }
            public DateTime ActionDate { get; set; }
        }
    }
    
    


    Step 4: Create a Context class

    Create HRMContext Class in Model folder.

    using Microsoft.AspNet.Identity.EntityFramework;
    using System.Data.Entity;
    
    namespace Web.HRM.Models
    {
    
        public class HRMContext : IdentityDbContext
        {
            public HRMContext()
                : base("DefaultConnection", throwIfV1Schema: false)
            {
            }
    
            public static HRMContext Create()
            {
                return new HRMContext();
            }
    
            public DbSet Depts { get; set; }
            public DbSet Designations { get; set; }
            public DbSet Employees { get; set; }
        }
    }
    
    

    Step 5: Create Controller and Views
    Click Right button on Controller Folder->Add Controller. Now choose scaffolding template as follows. Click Add.

    0106_04

    Now select context, model name and type controller name as EmployeeController as follows.

    0106_05

    Step 6: Modify the controller
    Modify EmployeeController as follows.

    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Linq;
    using System.Net;
    using System.Web.Mvc;
    using Web.HRM.Models;
    
    namespace Web.HRM.Controllers
    {
        public class EmployeeController : Controller
        {
            private HRMContext db = new HRMContext();
    
            // GET: /Employee/
            public ActionResult Index()
            {
                var employees = db.Employees.Include(e => e.Dept).Include(e => e.Designation);
                return View(employees.ToList());
            }
    
            // GET: /Employee/Details/5
            public ActionResult Details(int? id)
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Employee employee = db.Employees.Find(id);
                if (employee == null)
                {
                    return HttpNotFound();
                }
                return View(employee);
            }
    
            // GET: /Employee/Create
            public ActionResult Create()
            {
                ViewBag.DeptId = new SelectList(db.Depts, "Id", "Name");
                ViewBag.DesignationId = new SelectList(db.Designations, "Id", "Name");
    
                List lstDept = db.Depts.ToList();
                ViewBag.DeptList = lstDept;
    
                List lstDesignation = db.Designations.ToList();
                ViewBag.DesignationList = lstDesignation;
    
                return View();
            }
    
            // POST: /Employee/Create
            // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
            // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Create([Bind(Include = "Id,EmpCode,FullName,NickName,DesignationId,DeptId,Phone,Email,Address")] Employee employee)
            {
                if (ModelState.IsValid)
                {
                    employee.ActionDate = DateTime.Now;
                    if (employee.Id != 0)
                        db.Entry(employee).State = EntityState.Modified;
                    else
                        db.Employees.Add(employee);
                    db.SaveChanges();
                    return RedirectToAction("Create");
                }
    
                ViewBag.DeptId = new SelectList(db.Depts, "Id", "Name", employee.DeptId);
                ViewBag.DesignationId = new SelectList(db.Designations, "Id", "Name", employee.DesignationId);
                return View(employee);
            }
    
            // GET: /Employee/Edit/5
            public ActionResult Edit(int? id)
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Employee employee = db.Employees.Find(id);
                if (employee == null)
                {
                    return HttpNotFound();
                }
                ViewBag.DeptId = new SelectList(db.Depts, "Id", "Name", employee.DeptId);
                ViewBag.DesignationId = new SelectList(db.Designations, "Id", "Name", employee.DesignationId);
                return View(employee);
            }
    
            // POST: /Employee/Edit/5
            // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
            // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Edit([Bind(Include = "Id,EmpCode,FullName,NickName,DesignationId,DeptId,Phone,Email,Address,ActionDate")] Employee employee)
            {
                if (ModelState.IsValid)
                {
                    db.Entry(employee).State = EntityState.Modified;
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
                ViewBag.DeptId = new SelectList(db.Depts, "Id", "Name", employee.DeptId);
                ViewBag.DesignationId = new SelectList(db.Designations, "Id", "Name", employee.DesignationId);
                return View(employee);
            }
    
            // GET: /Employee/Delete/5
            public ActionResult Delete(int? id)
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Employee employee = db.Employees.Find(id);
                if (employee == null)
                {
                    return HttpNotFound();
                }
    
                return View(employee);
            }
    
            // POST: /Employee/Delete/5
            [HttpPost, ActionName("Delete")]
            [ValidateAntiForgeryToken]
            public ActionResult DeleteConfirmed(int id)
            {
                Employee employee = db.Employees.Find(id);
                db.Employees.Remove(employee);
                db.SaveChanges();
                return RedirectToAction("Create");
                //return RedirectToAction("Index");
            }
    
    
            public ActionResult _LoadSearchEmployee(string desigId, string deptId)
            {
                List employee = new List();
                int _desigId = 0;
                int _deptId = 0;
                Int32.TryParse(desigId, out _desigId);
                Int32.TryParse(deptId, out _deptId);
    
                employee = db.Employees.Where(p => (p.DeptId == _deptId || _deptId == 0) &&
                    (p.DesignationId == _desigId || _desigId == 0)).ToList();
                return PartialView(employee);
            }
            protected override void Dispose(bool disposing)
            {
                if (disposing)
                {
                    db.Dispose();
                }
                base.Dispose(disposing);
            }
        }
    }
    

    Step 7: Create a partial view
    Create a partial view name _LoadSearchEmployee in Employee Controller. Click right button on _LoadSearchEmployee action -> Add View -> Select “Create as a partial view” as follows.

    0106_06

    Modify the partial view “_LoadSearchEmployee” in Views-> Employee folder as follows.

    @model IEnumerable
    
        @{
            ViewBag.Title = "View1";
        }
    
        

    List of Employees

    @*

    @Html.ActionLink("Create New", "Create")

    *@ @foreach (var item in Model) { }
    @Html.DisplayNameFor(model => model.EmpCode) @Html.DisplayNameFor(model => model.FullName) @Html.DisplayNameFor(model => model.NickName) @Html.DisplayNameFor(model => model.Designation.Name) @Html.DisplayNameFor(model => model.Dept.Name) @Html.DisplayNameFor(model => model.Phone) @Html.DisplayNameFor(model => model.Email)
    @Html.DisplayFor(modelItem => item.EmpCode) @Html.DisplayFor(modelItem => item.FullName) @Html.DisplayFor(modelItem => item.NickName) @Html.DisplayFor(modelItem => item.Designation.Name) @Html.DisplayFor(modelItem => item.Dept.Name) @Html.DisplayFor(modelItem => item.Phone) @Html.DisplayFor(modelItem => item.Email) | @Html.ActionLink("Details", "Details", new { id = item.Id }) | @Html.ActionLink("Delete", "Delete", new { id = item.Id })

    Step 8: Create a View
    Right click on Create action -> Add View as follows.

    0106_07

    Modify the “Create” View and javascript bottom of the view in View->Employee folder as follows.

    
    @model Web.HRM.Models.Employee
    
    @{
        ViewBag.Title = "Create";
    
        var lstDept = ViewBag.DeptList;
        var lstDesignation = ViewBag.DesignationList;
    
    }
    
    @*

    Create

    *@ @using (Html.BeginForm()) { @Html.AntiForgeryToken()

    Employee Information


    @Html.ValidationSummary(true) @*@Html.HiddenFor(model => model.Id)*@
    @Html.LabelFor(model => model.EmpCode, new { @style = "width : 150px", @class = "control-label col-md-2" }) @Html.EditorFor(model => model.EmpCode) @Html.ValidationMessageFor(model => model.EmpCode) @Html.LabelFor(model => model.FullName, new { @style = "width : 150px", @class = "control-label col-md-2" }) @Html.EditorFor(model => model.FullName) @Html.ValidationMessageFor(model => model.FullName)
    @Html.LabelFor(model => model.NickName, new { @style = "width : 150px", @class = "control-label col-md-2" }) @Html.EditorFor(model => model.NickName) @Html.ValidationMessageFor(model => model.NickName) @Html.LabelFor(model => model.DesignationId, "Designation", new { @style = "width : 150px", @class = "control-label col-md-2" }) @Html.DropDownList("DesignationId", "---Select Dept---") @Html.ValidationMessageFor(model => model.DesignationId)
    @Html.LabelFor(model => model.DeptId, "Dept", new { @style = "width : 150px", @class = "control-label col-md-2" }) @Html.DropDownList("DeptId", "---Select Dept---") @Html.ValidationMessageFor(model => model.DeptId) @Html.LabelFor(model => model.Phone, new { @style = "width : 150px", @class = "control-label col-md-2" }) @Html.EditorFor(model => model.Phone) @Html.ValidationMessageFor(model => model.Phone)
    @Html.LabelFor(model => model.Email, new { @style = "width : 150px", @class = "control-label col-md-2" }) @Html.EditorFor(model => model.Email) @Html.ValidationMessageFor(model => model.Email) @Html.LabelFor(model => model.Address, new { @style = "width : 150px", @class = "control-label col-md-2" }) @Html.EditorFor(model => model.Address) @Html.ValidationMessageFor(model => model.Address)
    || @Html.ActionLink("Clear", "Create", "Employee", null, new { @class = "btn btn-primary" }) @*@Html.ActionLink("Back to List", "Index")*@

    @Html.Label("Dept: ", new { @style = "width : 150px", @class = "control-label col-md-2" }) @Html.DropDownList("DeptSearch", new SelectList(lstDept, "Id", "Name"), "---Select Dept---", new { @style = "width : 200px", @class = "form-control" }) @Html.Label("Designation: ", new { @class = "control-label col-md-2" }) @Html.DropDownList("DesigSearch", new SelectList(lstDesignation, "Id", "Name"), "---Select Designation---", new { @style = "width : 200px", @class = "form-control" })
    } @*
    @Html.ActionLink("Back to List", "Index")
    *@


    @{ Html.RenderAction("_LoadSearchEmployee", new { desigId = "", deptId = "" }); }
    @section Scripts { @Scripts.Render("~/bundles/jqueryval") }

    Step 9: Modify the RouteConfig
    Modify route configuration in App_Start in RouteConfig.cs is as follows. Main reason to modify this class to run the create page by default.

     
    using System.Web.Mvc;
    using System.Web.Routing;
    
    namespace Web.HRM
    {
        public class RouteConfig
        {
            public static void RegisterRoutes(RouteCollection routes)
            {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
                routes.MapRoute(
                    name: "Default",
                    url: "{controller}/{action}/{id}",
                    defaults: new { controller = "Employee", action = "Create", id = UrlParameter.Optional }
                );
            }
        }
    }
    

    Now run the application, you will see the following output. You can add, view, update and delete employee information in a same page. Thanks for your patience.

    0106_08

    Certificate Awarding Ceremony of C#.NET Applied OOP (Batch 01 to Batch 04)

    Mr. Zunaid Ahmed Palak, M.P; Honorable State Minister; ICT Division, Ministry of Post, Telecommunication & Information Technology; Government of the People’s Republic of Bangladesh was graciously present as Chief Guest, and handed over the certificates to successful trainees. The ceremony was chaired by Mr. Md. Harunur Rashid, Additional Secretary, Information and Communication Technology Division. Mrs. Hosne Ara Begum ndc, Managing Director, Bangladesh Hi-Tech Park Authority and Mr. A. N. M Safiqul Islam, Project Director, Support to Development of Kaliakoir Hi-Tech Park Project were also present as Special Guests. Honorable Chairman of LEADS Group Mr. Shaikh Abdul Aziz and Honorable Managing Director of LEADS Group Mr. Shaikh A Wahed were also present at the ceremony.
    The training was organized by LEADS Technology Limited and supported by Bangladesh Hi-Tech Park Authority.

    Date: 24 November 2015
    Venue: Bangladesh Hi-Tech Park Auditorium

    Last class of C#.NET Applied OOP Training (Batch – 04)

    Last class of C#.NET Applied OOP Training (Batch – 04) on 13 November 2015
    Training Title: C#.NET Applied OOP
    Organized by: Bangladesh Hi-Tech Park Authority (BHTPA) and Leads Technology Limited
    Total Duration: 144 Hours
    Trainer: Md. Mahedee Hasan