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

    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

    Cascading Dropdown List in ASP.Net MVC a sample demonstration

    Last couple of weeks I found a good number of requests from my trainees and some .NET developers. They request me for sample code or a demonstration of cascading dropdown list in ASP.NET MVC. That’s why, I am writing this article. Cascading dropdown list is actually a parent child dropdown list. In this article I showed two dropdown lists one is category dropdown list and other is product dropdown list. Product dropdown list will be populated on the basis of category (selected category).

    Let’s implement cascading dropdown list in ASP.NET MVC

    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. JQuery Ajax

    Step 1: Create a ASP.NET MVC Project
    Open visual studio and then go
    File -> Project -> ASP.NET Web Application
    Create an ASP.NET MVC project

    Step 2: Install Json.NET
    Click right button on Project -> NuGet Packages

    2015-12-04-01

    • Select and install Json.NET

    2015-12-04-02

    Keep note that in this moment, your internet connection must on.

    Step 3: Create a local database
    Click right button on App_Data folder -> Select Add -> SQL Server Database.

    2015-12-04-03

    Type Item name as InventoryDB. You can choose any type you want. You will see Inventory.mdf file is created in App_Data folder

    Step 4: Modify connection string.
    Modify connection string as below because you are using localdb.

    
      
        
      
    
    

    Step 5: Create a model for the application.

    Create a model name Category in model folder

        public class Category
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public List Products { get; set; }
        }
    

    Create a model name Product in model folder

        public class Product
        {
            public int Id { get; set; }
            public string Name { get; set; }
    
            public int CategoryId { get; set; }
    
            [ForeignKey("CategoryId")]
            public virtual Category Category { get; set; }
        }
    

    Create a model name Item in model folder

        public class Item
        {
            public int Id { get; set; }
            public string Name { get; set; }
    
            [Display(Name = "Category")]
            public int CategoryId { get; set; }
            [ForeignKey("CategoryId")]
            public virtual Category Category { get; set; }
    
            [Display(Name = "Products")]
            public int ProductId { get; set; }
            [ForeignKey("ProductId")]
            public Product Product { get; set; }
        }
    
    

    Step 6: Create Context Class
    Create a context class in model folder name InventoryDBContext as follows

        public class InventoryDBContext : DbContext
        {
            public InventoryDBContext()
                : base("DefaultConnection")
            {
    
            }
    
            public DbSet Categories { get; set; }
            public DbSet Products { get; set; }
            public DbSet Items { get; set; }
        }
    
    

    Step 7: Enable Migration

    Go to Tools-> NuGet Package Manager -> Package Manger Console
    Type the following command in package manager console to enable migration
    PM> Enable-Migrations -ContextTypeName InventoryDBContext

    After pressing enter you will see a class name Configuration is created in Migrations folder with some codes.
    Now add seed data in Seed method of Configuration class in Migrations folder as follows.

        internal sealed class Configuration : DbMigrationsConfiguration
        {
            public Configuration()
            {
                AutomaticMigrationsEnabled = false;
            }
    
            protected override void Seed(Web.Mahedee.net.Models.InventoryDBContext context)
            {
                context.Categories.AddOrUpdate(
                    p => p.Name,
                    new Category
                    {
                        Name = "Electronics",
                        Products = new List { 
                            new Product{Name = "Mobile"},
                            new Product{Name = "Laptop"},
                            new Product{Name = "Television"},
                            new Product{Name = "Camera"}
                        }
    
                    },
    
                    new Category
                    {
                        Name = "Men ware",
                        Products = new List 
                        { 
                            new Product{Name = "Footware"},
                            new Product{Name = "Clothings"},
                            new Product{Name = "Watches"},
                            new Product{Name = "Hand bag"},
                            new Product{Name = "Sun Glass"}
                        }
                    },
    
                    new Category
                    {
                        Name = "Baby & Kids",
                        Products = new List 
                        { 
                            new Product{Name = "Baby footware"},
                            new Product{Name = "Kids clothigs"},
                            new Product{Name = "Baby care"}
                        }
                    },
    
                     new Category
                    {
                        Name = "Books",
                        Products = new List 
                        { 
                            new Product{Name = "Introduction to C#"},
                            new Product{Name = "ASP.NET MVC Begineer to Professional"},
                            new Product{Name = "ASP.NET Web API Security"},
                            new Product{Name = "SPA with ASP.NET MVC"}
                        }
                    }
    
                    );
            }
        }
    

    Step 8: Add Migration and Update database
    In package manager console write the following command to add a migration.

    PM> add-migration firstmigration

    A file will be created in Migrations folder something like below.
    File Name: 201512041037292_firstmigration

    Update the file, in AddForeignKey section and set false for cascadeDelete as follows.

       public partial class firstmigration : DbMigration
        {
            public override void Up()
            {
                DropForeignKey("dbo.Categories", "Item_Id", "dbo.Items");
                DropForeignKey("dbo.Products", "Item_Id", "dbo.Items");
                DropIndex("dbo.Categories", new[] { "Item_Id" });
                DropIndex("dbo.Products", new[] { "Item_Id" });
                CreateIndex("dbo.Items", "CategoryId");
                CreateIndex("dbo.Items", "ProductId");
    
                AddForeignKey("dbo.Items", "CategoryId", "dbo.Categories", "Id", cascadeDelete: false);
                AddForeignKey("dbo.Items", "ProductId", "dbo.Products", "Id", cascadeDelete: false);
    
                DropColumn("dbo.Categories", "Item_Id");
                DropColumn("dbo.Products", "Item_Id");
            }
            
            public override void Down()
            {
                AddColumn("dbo.Products", "Item_Id", c => c.Int());
                AddColumn("dbo.Categories", "Item_Id", c => c.Int());
                DropForeignKey("dbo.Items", "ProductId", "dbo.Products");
                DropForeignKey("dbo.Items", "CategoryId", "dbo.Categories");
                DropIndex("dbo.Items", new[] { "ProductId" });
                DropIndex("dbo.Items", new[] { "CategoryId" });
                CreateIndex("dbo.Products", "Item_Id");
                CreateIndex("dbo.Categories", "Item_Id");
                AddForeignKey("dbo.Products", "Item_Id", "dbo.Items", "Id");
                AddForeignKey("dbo.Categories", "Item_Id", "dbo.Items", "Id");
            }
        }
    

    Write the following command in package manager console to update database.
    PM> update-database –Verbose

    Step 9: Add Items Controller

    • Right click on Controllers folder -> Add -> Controller
    • Select MVC 5 Controller with views using Entity Framework and the click Add

    2015-12-04-04

    • Select Item as Model class and InventoryDBContext as context class and click Add button as follows

    2015-12-04-05

    ItemsController and Views will be created automatically.

    Step 10: Update Items controller

    • Modify the following action of Items controller
            public ActionResult Create()
            {
                List lstCategory = db.Categories.ToList();
                lstCategory.Insert(0, new Category { Id = 0, Name = "--Select Category--" });
    
                List lstProduct = new List();
                ViewBag.CategoryId = new SelectList(lstCategory, "Id", "Name");
                ViewBag.ProductId = new SelectList(lstProduct, "Id", "Name");
                return View();
            }
    
    
    • Add the following action in the Items controller
            public JsonResult GetProductsByCategoryId(int id)
            {
                List products = new List();
                if (id > 0)
                {
                    products = db.Products.Where(p => p.CategoryId == id).ToList();
    
                }
                else
                {
                    products.Insert(0, new Product { Id = 0, Name = "--Select a category first--" });
                }
                var result = (from r in products
                              select new
                              {
                                  id = r.Id,
                                  name = r.Name
                              }).ToList();
    
                return Json(result, JsonRequestBehavior.AllowGet);
            }
    
    

    Step 5: Modify the Create View of Items folder
    Modify the Create View as follows.

    @model Web.Mahedee.net.Models.Item
    
    @{
        ViewBag.Title = "Create";
    }
    
    
    
    
    

    Create

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

    Item


    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @Html.LabelFor(model => model.CategoryId, "Category", htmlAttributes: new { @class = "control-label col-md-2" })
    @Html.DropDownList("CategoryId", null, htmlAttributes: new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.CategoryId, "", new { @class = "text-danger" })
    @Html.LabelFor(model => model.ProductId, "Product", htmlAttributes: new { @class = "control-label col-md-2" })
    @Html.DropDownList("ProductId", null, htmlAttributes: new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.ProductId, "", new { @class = "text-danger" })
    @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
    }
    @Html.ActionLink("Back to List", "Index")
    @section Scripts { @Scripts.Render("~/bundles/jqueryval") }

    Now run the application and type the following URL .

    http://localhost:61767/Items/Create

    You will see the following output. Now select category from category dropdown lsit, you will see product dropdown list is populating on corresponding category.

    2015-12-04-06

    Means, it’s working…!! Cheers!!!

    ASP.NET Application Performance Tuning and Scalability Improvement (Part – 1)

    Every developers and customer wants his/her application performed well. But it is very tricky to improve performance of a web application. It’s actually depends on different parameter like HTML client, HTTP network, Web server, middle-tier components, database components, resource-management components, TCP/IP networks, and database servers. Sometimes performance of the application increases drastically, if you change a single parameter. Sometimes you have to change multiple parameters. Here are the some performance optimization tips for ASP.NET web applications which may help you to increase performance of ASP.NET Application.

    Prepare release with release mode
    When prepare release for deployment, select release mode instead of debug mode.

    How affect in performance?

    • If you choose debug mode instead of release mode, you are creating pdb (program database – uses for debugging) files which creates extra overhead. For this reason you may face timeout problem.

    Best Practice

    • Always prepare release in release mode.

    Release mode

    In Web.Config, Set debug=”false”
    Set debug=”false” in web.config as follows after deploying your application. By default debug=”true” when you create a web application. It is necessary to set debug=”true” in development environment.

      
        
      
    

    How affect in performance?

    • If you set debug = “true”, application requires the pdb information to be inserted into the file and that results in a comparatively larger file and hence processing will be slow.

    Best Practice

    • In deployment server, set debug = “false” in web.config

    Turn off Tracing unless until required
    Sometimes developers need to trace the application to monitor the executions of application or a pages. It requires for application diagnostic purposes.

    How affect in performance?

    • When trace is enabled it loaded extra information to the pages which degrades performances.

    Best Practice

    • Always set trace enabled = “false” unless or until you required to monitor a page’s executions. Set trace enable = “false” as follows in web.config.
    
        
    
    

    Carefully manage session state
    Session state is a very useful feature of asp.net. Though, ASP.NET manages session state by default, we must pay attention of session memory management.

    • How affect in performance?
    • When you store your data in in-process or on a state server or in a SQL Database, session state, it requires memory.
    • It is also time consuming when you store or retrieve data in-process or state server or SQL server.

    Best Practice

    • If your page is static, it is recommended not to use session state. In such cases where you don’t need to use session state, disable it on your web form using the following directive:
      <@%Page EnableSessionState="false"%>
    • In case you use the session state only to retrieve data and not to update, make the session state read-only using the following directive.
      <@%Page EnableSessionState ="ReadOnly"%>
    • If your application session state is out of process then consider carefully whether there is a need of the state server or SQL Server mode.
    • SQL Server session mode provides lower performance than state server mode.
    • Try to avoid keeping object in session. Since it requires serializing then de-serializing which affected in performance.
    • Use client-side state management than server side.

    Disable View State of a page if not required

    • It stores data in the generated HTML using hidden field not on the server.
    • View State provides page level state management
    • As long as the user is on the current page, state is available and the user redirects to the next page and the current page state is lost
    • View State can store any type of data because it is object type but it is preferable not to store a complex type of data due to the need for serialization and deserialization on each post back

    How affect in performance?

    • It increases the total payload of a page when submitted and when serving request.
    • Serialization and deserialization of the data is required when submitting data and gets requested data.
    • View state increases the memory allocations on the server.

    Best Practice

    • Pages that do not have any server postback events can have the view state turned off.
    • The default behaviour of the View State property is enabled, but if you don’t need it, you can turn it off at the control or page level.
    • Within a control, simply set the EnableViewState property to false, or set it globally within the page using this setting.

      <%@ Page EnableViewState="false" %>

    Use finally block to release resources
    We always uses try, catch and finally block for exception handling. Finally block executes whether any exception occurs or not.
    How affect in performance?

    • Sometimes application occupy resources where as it doesn’t need it. It is occur due to bad programming.

    Best Practice

    • Always use a finally block to release resources like closing database connections, closing files, disposing objects and other resources.

    Avoid unnecessary round trips to the server

    How affect in performance?

    • Unnecessary round trips significantly effect on web application performance.
    • It increases network latency and downstream server latency.
    • Many data-driven Web sites heavily access the database for every user request. While connection pooling helps, the increased network traffic and processing load on the database server can adversely affect performance.

    Best Practice

    • Keep round trips as minimum as possible
    • Use Ajax or partial page load instead of full page reload or refresh.

    Choose low cost authentication
    Authentication is a main factor for a secured applications. You must take decision which authentication will you use? Keep in mind, passport authentication is slower than form-base authentication which is slower than Windows authentication.

    Use paging in grid view
    In asp.net web application to show data in tabular format, generally we use grid view. Besides this we also uses DataGrid, JQgrid, Telerik grid, Kendo Grid etc. For huge number of data we cannot think general way because it takes huge time to load.

    Best Practice

    • To load grid view faster take advantages of paging, it shows small subsets of data at a time. JQGrid is faster than asp.net grid view because it does everything in client side.

    Minimizes number of web server control

    How affect in performance?

    • The uses of web server controls increase the response time.
    • Web server controls go to the server executes all of its life cycle and then rendered on the client side.

    Best Practice

    • Don’t use server control unless until required. Use HTML elements where suited.

    Introduction to OData Services using ASP.NET Web API

    What is OData?

    OData Stands for Open Data Protocol. It is a data access protocol for the web. OData provides a uniform way to query and manipulate data sets through CRUD operations (create, read, update, and delete). OData consumption can be done across different Programming Language. ASP.NET Web API supports both OData v3 and V4.

    Advantages of OData Services

    • OData based on REST Architecture so we can retrieve data using URL
    • Support CRUD Operation using HTTP Method like GET, POST, PUT, DELETE
    • Support HTTP, JSON and Atom Pub
    • It is very light weight, so interaction of client and server is very fast

    Disadvantage

    • Since it is URL based so many people think it is less secure
    • It does not support all type of custom query

    Let’s implement OData Services using ASP.NET Web API

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

    • Visual Studio 2013
    • Visual C#
    • ASP.NET Web API 2
    • Entity Framework 6
    • Postman(Google postman)

    Step 1: Create a ASP.net Web API Project
    Open visual studio and then go
    File -> Project -> ASP.NET Web Application

    01

    Now select Web API and press OK

    2

    Step 2: Install Microsoft.AspNet.Odata

    To install OData Nuget Pacakge from Package Manager Console.
    Select Tool -> NuGet Package Manager > Package Manager Console
    Type following command in package manager console

    PM> Install-Package Microsoft.AspNet.Odata

    Step 3: Create a model name Employee

    Create a Model name Employee in model folder

    
        public class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Designation { get; set; }
            public string Dept { get; set; }
            public string BloodGroup { get; set; }
        }
    
    

    Step 4: Change or Add Connection String
    Change or Add connection string in Web.config

    
    

    Step 5: Create a Context class

    Create HRMContext class in Model  folder.
    
        public class HRMContext : DbContext
        {
            public HRMContext()
                : base("DefaultConnection")
            {
            }
            public DbSet<Employee> Employees { get; set; }
        }
    

    Step 6: Add a Controller

    Press right button on Controller folder -> Add -> Controller

    Now choose “Web API 2 OData v3 Controller with actions, using Entity Framework” scaffolding template and then press Add.

    3

    Now choose Controller Name as EmployeeController, Model name as Employee and Context name as HRMContext and click Add like below.

    04

    The following code will be generated on corresponding for the controller.

        public class EmployeeController : ODataController
        {
            private HRMContext db = new HRMContext();
    
            // GET: odata/Employee
            [EnableQuery]
            public IQueryable<Employee> GetEmployee()
            {
                return db.Employees;
            }
    
            // GET: odata/Employee(5)
            [EnableQuery]
            public SingleResult<Employee> GetEmployee([FromODataUri] int key)
            {
                return SingleResult.Create(db.Employees.Where(employee => employee.Id == key));
            }
    
            // PUT: odata/Employee(5)
            public IHttpActionResult Put([FromODataUri] int key, Delta patch)
            {
                Validate(patch.GetEntity());
    
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
    
                Employee employee = db.Employees.Find(key);
                if (employee == null)
                {
                    return NotFound();
                }
    
                patch.Put(employee);
    
                try
                {
                    db.SaveChanges();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!EmployeeExists(key))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
    
                return Updated(employee);
            }
    
            // POST: odata/Employee
            public IHttpActionResult Post(Employee employee)
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
    
                db.Employees.Add(employee);
                db.SaveChanges();
    
                return Created(employee);
            }
    
            // PATCH: odata/Employee(5)
            [AcceptVerbs("PATCH", "MERGE")]
            public IHttpActionResult Patch([FromODataUri] int key, Delta patch)
            {
                Validate(patch.GetEntity());
    
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
    
                Employee employee = db.Employees.Find(key);
                if (employee == null)
                {
                    return NotFound();
                }
    
                patch.Patch(employee);
    
                try
                {
                    db.SaveChanges();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!EmployeeExists(key))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
    
                return Updated(employee);
            }
    
            // DELETE: odata/Employee(5)
            public IHttpActionResult Delete([FromODataUri] int key)
            {
                Employee employee = db.Employees.Find(key);
                if (employee == null)
                {
                    return NotFound();
                }
    
                db.Employees.Remove(employee);
                db.SaveChanges();
    
                return StatusCode(HttpStatusCode.NoContent);
            }
    
            protected override void Dispose(bool disposing)
            {
                if (disposing)
                {
                    db.Dispose();
                }
                base.Dispose(disposing);
            }
    
            private bool EmployeeExists(int key)
            {
                return db.Employees.Count(e => e.Id == key) > 0;
            }
        }
    
    

    Step 7: Configure OData End Point

    Open the file App_Start/WebApiConfig.cs. Add the following using statements:

    using System.Web.Http.OData.Builder;
    using System.Web.Http.OData.Extensions;
    using Web.OData.Models;

    Add the following code in the register method.

    
        public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
                builder.EntitySet("Employee");
    config.Routes.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
    }
    }
    

    Step 8: Enable Migration

    Type the following command in package manager console to enable migration
    PM> Enable-Migrations -ContextTypeName HRMContext

    After pressing enter you will see a class name Configuration is created in Mingrations folder with some codes.

    Step 9: Add seed data and add migration

    Modify the Seed() method of Configuration class like below to add some seed data.

            protected override void Seed(Web.OData.Models.HRMContext context)
            {
    
                context.Employees.AddOrUpdate(
                  p => p.Name,
                  new Employee { Name = "Mahedee Hasan", Designation = "Software Architect", Dept = "SSD", BloodGroup = "A+" },
                  new Employee { Name = "Kazi Aminur Rashid", Designation = "AGM", Dept = "SSD", BloodGroup = "NA" },
                  new Employee { Name = "Tauhidul Haque", Designation = "DGM", Dept = "SSD", BloodGroup = "A+" }
                );
    
    }
    
    

    Now type the following command in the package manager console to add a migration.

    PM> Add-Migration initialmigration

    Step 10: Update database and attaché mdf file

    Now type the following command in package manager console.

    PM> Update-Database –Verbose

    You will see two file .mdf and .ldf is created in your App_data directory. Now attached the file like below.

    05

    Now run you application. Run Postman. Type http://localhost:64126/odata/Employee in your postbox you will see following output in JSON format. Use port number on which your application currently running instead of 64126.

    06

    Now, it’s working…!! Cheers!!!

    Multiple DbContext in a single asp.net mvc applications with EF code first

    Is it possible to create multiple DbContext in a single asp.net application with entity framework code first? Yes! Then, How!! This was the questions to me for a couple of weeks. Here is the simple article where you will get all answer. First, I want to say, yes it is possible to create multiple DbContext in a single asp.net application with entity framework code first.

    Let’s see how to create multiple DbContext

    Tools and Technology used
    I used following tools and technology for my project –

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

    Here, I have an application name PMTool with two DbContext name PMToolContext and SecurityContext.

    Step 1: Enable Migration
    If you run only Enable-Migrations in package manager console, you will get following error.

    PM> Enable-Migrations
    More than one context type was found in the assembly 'PMTool'.
    To enable migrations for 'PMTool.Repository.SecurityContext', use Enable-Migrations -ContextTypeName PMTool.Repository.SecurityContext.
    To enable migrations for 'PMTool.Repository.PMToolContext', use Enable-Migrations -ContextTypeName PMTool.Repository.PMToolContext.
    

    So you have to run enable-migration for each context. You have to specify the directory for each Configuration.cs also. Now run the command in package manager console in the following way.

    PM> Enable-Migrations -ContextTypeName PMToolContext -MigrationsDirectory Migrations\PMToolContext
    Checking if the context targets an existing database...
    Code First Migrations enabled for project PMTool.
    PM> Enable-Migrations -ContextTypeName SecurityContext -MigrationsDirectory Migrations\SecurityContext
    Checking if the context targets an existing database...
    Code First Migrations enabled for project PMTool.
    

    Step 2: Add Migration
    Use fully qualified name of the configuration class as follows.

    PM> Add-Migration -ConfigurationTypeName PMTool.Migrations.PMToolContext.Configuration FirstMigForPMTool
    Scaffolding migration 'FirstMigForPMTool'.
    
    PM> Add-Migration -ConfigurationTypeName PMTool.Migrations.SecurityContext.Configuration FirstMigForSecurity
    Scaffolding migration 'FirstMigForSecurity'.
    

    Step 3: Update database

    Now update the database. Use fully qualified name of configuration class here also.

    PM> Update-Database -ConfigurationTypeName PMTool.Migrations.PMToolContext.Configuration
    Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
    Applying explicit migrations: [201512071619030_FirstMigForPMTool].
    Applying explicit migration: 201512071619030_FirstMigForPMTool.
    Running Seed method.
    PM> Update-Database -ConfigurationTypeName PMTool.Migrations.SecurityContext.Configuration
    Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
    Applying explicit migrations: [201512071627058_FirstMigForSecurity].
    Applying explicit migration: 201512071627058_FirstMigForSecurity.
    Running Seed method.
    

    If each commands run individually, means you could use multiple DbContext in an asp.net web application with Entity framework. Let’s cheer!!

    Dependency Injection using Ninject in ASP.NET MVC

    What is Dependency Injection?
    In software engineering, dependency injection is a software design pattern that implements inversion of control for resolving dependencies. – Wikipedia. It makes software components are loosely coupled.

    Advantages of Dependency Injection
    • Flexibility to use alternative implementation of service.
    • Configurable & easy to use
    • Make system loosely couple
    • Code becomes more reusable, testable, readable and manageable.
    • Reduction of boilerplate code in the application objects

    What is Ninject?
    • Open Source Inversion of Control (IOC)
    • It is a Dependency Injector for .NET created by Nate Kohari
    • It’s very easy to use.
    • Easily add from nuget.
    • For more information visit Ninject.org
    Let’s come to the implementation of DI using Ninject in ASP.NET MVC

    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. Ninject for MVC5

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

    01

    Select MVC Template and click OK

    02

    Step 2: Create a model name Employee

    Create a Model name Employee in model folder

        public class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Designation { get; set; }
            public string Dept { get; set; }
            public string BloodGroup { get; set; }
        }
    
    

    Step 3: Change or Add Connection String
    Change or Add connection string in Web.config

    
     
         
      
    
    

    Step 4: Create a Context class

    
    Create HRMContext Class in Repository folder.
    
        public class HRMContext : DbContext
        {
            public HRMContext()
                : base("DefaultConnection")
            {
            }
            public DbSet < Employee > Employees { get; set; }
        }
    
    

    Step 5: Create Repository Interface and Concrete Class
    Create IEmployeeRepository Interface and EmployeeRepository class in Repository folder

        public interface IEmployeeRepository : IDisposable
        {
            IQueryable  All { get; }
            Employee Find(int? id);
            void InsertOrUpdate(Employee employee);
            void Delete(int id);
            void Save();
        }
    
    
        public class EmployeeRepository : IEmployeeRepository
        {
    
            HRMContext context;
            public EmployeeRepository(HRMContext context)
            {
                this.context = context;
            }
    
            public IQueryable  All
            {
                get { return context.Employees; }
            }
    
            public Employee Find(int? id)
            {
                Employee objEmployee = new Employee();
                objEmployee = context.Employees.Where(p => p.Id == id).FirstOrDefault();
                return objEmployee;
            }
    
            public void InsertOrUpdate(Employee employee)
            {
                if (employee.Id == default(int))
                {
                    // New entity
                    context.Employees.Add(employee);
                }
                else
                {
                    // Existing entity
                    context.Entry(employee).State = System.Data.Entity.EntityState.Modified;
                }
            }
    
            public void Delete(int id)
            {
                var employee = context.Employees.Find(id);
                context.Employees.Remove(employee);
            }
    
            public void Save()
            {
                context.SaveChanges();
            }
    
            public void Dispose()
            {
                context.Dispose();
            }
        }
    

    Step 6: Install Ninject from nuget

    03


    Step 7: Map Interface and Concrete class in Ninject

    Go to NinjectWebCommon file in App_Start folder. Add the following line for IEmployee Interface and Employee concrete class.

    public static class NinjectWebCommon 
        {
            private static readonly Bootstrapper bootstrapper = new Bootstrapper();
    
            /// 
            /// Starts the application
            /// 
            public static void Start() 
            {
                DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
                DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
                bootstrapper.Initialize(CreateKernel);
            }
            
            /// 
            /// Stops the application.
            /// 
            public static void Stop()
            {
                bootstrapper.ShutDown();
            }
            
            /// 
            /// Creates the kernel that will manage your application.
            /// 
            /// The created kernel.
            private static IKernel CreateKernel()
            {
                var kernel = new StandardKernel();
                try
                {
                    kernel.Bind>().ToMethod(ctx => () => new Bootstrapper().Kernel);
                    kernel.Bind().To();
    
                    kernel.Bind().To();
    
                    RegisterServices(kernel);
                    return kernel;
                }
                catch
                {
                    kernel.Dispose();
                    throw;
                }
            }
    
            /// 
            /// Load your modules or register your services here!
            /// 
            /// The kernel.
            private static void RegisterServices(IKernel kernel)
            {
            }        
        }
    
    

    Step 8: Create Controller and Views
    Click Right button on Controller Folder->Add Controller. Choose its name as EmployeeController. Now choose scaffolding template for the controller as follows.

    04

    After clicking Add button, Employee Controller and Corresponding actions and views will be created automatically.

    Step 9: Modify the controller

    Modify the controller – use repository instead of context directly.

        public class EmployeesController : Controller
        {
            private readonly IEmployeeRepository repository;
    
            public EmployeesController(IEmployeeRepository objIrepository)
            {
                repository = objIrepository;
            }
    
            // GET: Employees
            public ActionResult Index()
            {
                return View(repository.All.ToList());
            }
    
            // GET: Employees/Details/5
            public ActionResult Details(int? id)
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Employee employee = repository.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,Designation,Dept,BloodGroup")] Employee employee)
            {
                if (ModelState.IsValid)
                {
                    repository.InsertOrUpdate(employee);
                    repository.Save();
                    return RedirectToAction("Index");
                }
    
                return View(employee);
            }
    
            // GET: Employees/Edit/5
            public ActionResult Edit(int? id)
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Employee employee = repository.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,Designation,Dept,BloodGroup")] Employee employee)
            {
                if (ModelState.IsValid)
                {
                    repository.InsertOrUpdate(employee);
                    repository.Save();
                    return RedirectToAction("Index");
                }
                return View(employee);
            }
    
            // GET: Employees/Delete/5
            public ActionResult Delete(int? id)
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Employee employee = repository.Find(id);
                if (employee == null)
                {
                    return HttpNotFound();
                }
                return View(employee);
            }
    
            // POST: Employees/Delete/5
            [HttpPost, ActionName("Delete")]
            [ValidateAntiForgeryToken]
            public ActionResult DeleteConfirmed(int id)
            {
                repository.Delete(id);
                repository.Save();
                return RedirectToAction("Index");
            }
    
            protected override void Dispose(bool disposing)
            {
                if (disposing)
                {
                    repository.Dispose();
                }
                base.Dispose(disposing);
            }
        }
    
    

    Step 10: Run command in Package Manager Console

    To find Package manager console go to

    Tool->NuGet Package Manager -> Package Manager Console

    Now, build the application and run the following command one by one in Package Manager Console.

    PM> Enable-Migrations -ContextTypeName HRMContext
    PM> Add-Migration initialmigration
    PM> Update-Database -Verbose

    Step 11: Add a menu
    Add a menu name employee in _Layout.cshtml page to create a menu.

                    
    
    

    Run the application and click “Employee” menu. Now you can create, delete, read update employee information.

    05

    Generic Repository Pattern with ASP.NET MVC and Entity Framework

    Introduction
    You may introduce with an Object Oriented Design Principle name DRY – Don’t repeat yourself. It is more important in Multi-tier architecture. We can use generic repository pattern to implement DRY.

    What is Repository Pattern?
    In most of the business operation we have to perform CRUD (Create, Read, Update and Delete) operation. A repository basically works as a mediator between our business logic layer and our data access layer of the application

    Benefits of Repository Pattern

    • Centralizes data logic or service logic.
    • Provides a substitution point for the unit tests for both business logic and data access logic
    • Provides a flexible architecture
    • Can adopt new change easily
    • Domain driven development is easier


    What is Generic Repository Pattern?

    Generic Repository is a pattern by which we can use single repository for data access of all models. Generally, we used one repository for one model to access data.

    Benefits of Generic Repository Pattern

    • Reduce redundancy of code
    • Force developer to work same pattern – Possibility of less error or no error
    • Easy to maintain – Centralize data access logic

    Implementation Repository Pattern with ASP.NET MVC and Entity Framework

    Let’s consider a project to keep Employee Information. Here I will show CRUD operation on employee information.
    Tools and Technology used
    I used following tools and technology to develop the project – Implementation of generic repository

    • Visual Studio 2013
    • Visual C#
    • ASP.NET MVC 5
    • Entity Framework 6
    • Razor view engine


    Step 1:
    Create an ASP.NET MVC 5 application using Visual Studio 2013. I kept the application name “GenericRepo”.
    Help: How to create first application using asp.net MVC
    Step 2: Configure connection string in web.config

      
        
      
    

    Step 3: Create Model – “Employee”

        public class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string FatherName { get; set; }
            public string MotherName { get; set; }
            public string Designation { get; set; }
            public string Dept { get; set; }
        }
    

    Step 4: Create a DbContext name GenericDbContext in Repository folder.

        public class GenericRepoContext : DbContext
        {
            public GenericRepoContext()
                : base("DefaultConnection")
            {
            }
    
            public DbSet Employees { get; set; }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
    
            }
        }
    
    

    Step 5: Create IGenericRepository and GenericRepository in Repository folder

    
        interface IGenericRepository where T : class
        {
            IEnumerable SelectAll();
            T SelectByID(object id);
            void Insert(T obj);
            void Update(T obj);
            void Delete(object id);
            void Save();
        }
    
    public class GenericRepository : IGenericRepository where T : class
        {
            private GenericRepoContext db = null;
            private DbSet table = null;
            public GenericRepository()
            {
                this.db = new GenericRepoContext();
                table = db.Set();
            }
            public GenericRepository(GenericRepoContext db)
            {
                this.db = db;
                table = db.Set();
            }
            public IEnumerable SelectAll()
            {
                return table.ToList();
            }
            public T SelectByID(object id)
            {
                return table.Find(id);
            }
            public void Insert(T obj)
            {
                table.Add(obj);
            }
            public void Update(T obj)
            {
                table.Attach(obj);
                db.Entry(obj).State = EntityState.Modified;
            }
            public void Delete(object id)
            {
                T existing = table.Find(id);
                table.Remove(existing);
            }
            public void Save()
            {
                db.SaveChanges();
            }
        }
    
    

    Step 6:
    Create a controller name – EmployeeController. Select template “MVC5 Controller with read/write action”

        public class EmployeeController : Controller
        {
            private IGenericRepository repository = null;
            public EmployeeController()
            {
                this.repository = new GenericRepository();
            }
    
    
            // GET: Employee
            public ActionResult Index()
            {
                var employee = repository.SelectAll().ToList();
                return View(employee);
            }
    
            // GET: Employee/Details/5
            public ActionResult Details(int id)
            {
                var employee = repository.SelectByID(id);
                return View(employee);
            }
    
            // GET: Employee/Create
            public ActionResult Create()
            {
                return View();
            }
    
            // POST: Employee/Create
            [HttpPost]
            public ActionResult Create(Employee employee)
            {
                if (ModelState.IsValid)
                {
                    repository.Insert(employee);
                    repository.Save();
    
                    return RedirectToAction("Index");
                }
                return View(employee);
            }
    
            // GET: Employee/Edit/5
            public ActionResult Edit(int id)
            {
                var employee = repository.SelectByID(id);
                return View(employee);
            }
    
            // POST: Employee/Edit/5
            [HttpPost]
            public ActionResult Edit(Employee employee)
            {
                try
                {
                    repository.Update(employee);
                    repository.Save();
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
    
            // GET: Employee/Delete/5
            public ActionResult Delete(int id)
            {
                var employee = repository.SelectByID(id);
                return View(employee);
            }
    
            // POST: Employee/Delete/5
            [HttpPost]
            public ActionResult Delete(int id, FormCollection collection)
            {
                try
                {
                    repository.Delete(id);
                    repository.Save();
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    
    

    Step 7: Create List, Edit, Delete and details page against EmployeeController.
    Create a list view

    1-List

    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.MotherName) @Html.DisplayNameFor(model => model.Designation) @Html.DisplayNameFor(model => model.Dept)
    @Html.DisplayFor(modelItem => item.Name) @Html.DisplayFor(modelItem => item.FatherName) @Html.DisplayFor(modelItem => item.MotherName) @Html.DisplayFor(modelItem => item.Designation) @Html.DisplayFor(modelItem => item.Dept) @Html.ActionLink("Edit", "Edit", new { id=item.Id }) | @Html.ActionLink("Details", "Details", new { id=item.Id }) | @Html.ActionLink("Delete", "Delete", new { id=item.Id })

    Create Edit View
    Create edit view as like list view and choose edit template for that.
    _CreateOrEdit.cshtml

    @model GenericRepo.Models.Employee
    
        
    @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
    @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 = "control-label col-md-2" })
    @Html.EditorFor(model => model.FatherName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.FatherName, "", new { @class = "text-danger" })
    @Html.LabelFor(model => model.MotherName, htmlAttributes: new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.MotherName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.MotherName, "", new { @class = "text-danger" })
    @Html.LabelFor(model => model.Designation, htmlAttributes: new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.Designation, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Designation, "", new { @class = "text-danger" })
    @Html.LabelFor(model => model.Dept, htmlAttributes: new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.Dept, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Dept, "", new { @class = "text-danger" })


    Edit.cshtml

    @model GenericRepo.Models.Employee
    
    
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
    
        

    Employee


    @Html.ValidationSummary(true, "", new { @class = "text-danger" }) @Html.Partial("_CreateOrEdit", Model)
    }
    @Html.ActionLink("Back to List", "Index")
    @section Scripts { @Scripts.Render("~/bundles/jqueryval") }

    Create Delete View
    Create delete view as like list view and choose delete template for that.
    Delete.cshtml

    @model GenericRepo.Models.Employee
    
    

    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.MotherName)
    @Html.DisplayFor(model => model.MotherName)
    @Html.DisplayNameFor(model => model.Designation)
    @Html.DisplayFor(model => model.Designation)
    @Html.DisplayNameFor(model => model.Dept)
    @Html.DisplayFor(model => model.Dept)
    @using (Html.BeginForm()) { @Html.AntiForgeryToken()
    | @Html.ActionLink("Back to List", "Index")
    }

    Create Details View
    Create details view as like list view and choose details template for that.
    Details.cshtml

    @model GenericRepo.Models.Employee
    
    

    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.MotherName)
    @Html.DisplayFor(model => model.MotherName)
    @Html.DisplayNameFor(model => model.Designation)
    @Html.DisplayFor(model => model.Designation)
    @Html.DisplayNameFor(model => model.Dept)
    @Html.DisplayFor(model => model.Dept)

    @Html.ActionLink("Edit", "Edit", new { id = Model.Id }) | @Html.ActionLink("Back to List", "Index")

    Step 8: Add a link “Employee” to _Layout page like below

             
    

    Step 9: Write following command in package manager console
    PM> Enable-Migrations -ContextTypeName GenericRepoContext
    PM> Add-Migration initalcreate
    PM> Update-Database -Verbose -Force

    Now your project is ready. Run application and execute CRUD operation on it. Output of the application like below.
    Output:

    2

    CRUD Operation using asynchronous method in ASP.NET MVC

    Introduction
    In .NET framework 4.5 asynchronous programming concept has been introduced. In this regard, .NET introduced two keyword async and await. It is much easier to implement than the multi-threading concept. The .NET Framework 4 introduced an asynchronous programming concept referred to as a Task and ASP.NET MVC 4 supports Task. In this article I will show you a simple CRUD operation using asynchronous programming by async, await and Task.

    A simple overview on “async, await, Task” Keyword

    async

    • The async modifier indicates that the method, lambda expression, or anonymous method will work asynchronously.
    • Method with async modifier also called async method.
    • An async method provides a convenient way to do potentially long-running work without blocking the caller’s thread.
    • The caller of an async method can resume its work without waiting for the async method to finish.
    • Typically, a method modified by the async keyword contains at least one await expression or statement.

    await

    • Typically await keyword used to free a thread
    • The await operator is applied to a task in an asynchronous method to suspend the execution of the method until the awaited task completes.
    • The asynchronous method in which await is used must be modified by the async keyword. Such a method, defined by using the async modifier, and usually containing one or more await expressions, is referred to as an async method.
    • The task to which the await operator is applied typically is the return value from a call to a method that
    • implements.

    Task

    • The main types are System.Threading.Tasks.Task
    • Represents an asynchronous operation that can be waited on and cancelled
    • System.Threading.Tasks.Task, which is a task that can return a value.

    MSDN References:

    Here I implement async modifier to a CRUD operation on Employee Object. Let’s start.
    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

    Step 1: Create an ASP.NET MVC 5 application using Visual Studio 2013. I kept the application name “MVCAsync”.
    Help: How to create first application using asp.net MVC

    Step 2: Configure connection string in web.config

      
        
      
    

    Step 3: Create a model in model folder – Employee

    Employee

       public class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string NickName { get; set; }
            public string Designation { get; set; }
            public string Dept { get; set; }
        }
    

    Step 4: Create a DbContext name EmployeeDBContext in Model folder.

    
        public class EmployeeDBContext : DbContext
        {
            public EmployeeDBContext()
                : base("DefaultConnection")
            {
            }
    
            public DbSet Employees { get; set; }
        }
    
    

    Step 5: Create a controller name – EmployeeController. Select template “MVC5 Controller with views, using entity framework”. EmployeeController will create in Controller folder and related views will be created in Views/Employee folder. At the time of creating controller – mark use async controller action.

    01

    02

    Step 6: Employee Controller is given below. A simple difference over normal method is –

    • used async keyword in Action Method.
    • Used Task instead of typical ActionResult
    • And used await keyword in any operation.
       public class EmployeeController : Controller
        {
            private EmployeeDBContext db = new EmployeeDBContext();
    
            // GET: /Employee/
            public async Task Index()
            {
                return View(await db.Employees.ToListAsync());
            }
    
            // GET: /Employee/Details/5
            public async Task Details(int? id)
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Employee employee = await db.Employees.FindAsync(id);
                if (employee == null)
                {
                    return HttpNotFound();
                }
                return View(employee);
            }
    
            // GET: /Employee/Create
            public ActionResult Create()
            {
                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 async Task Create([Bind(Include="Id,Name,NickName,Designation,Dept")] Employee employee)
            {
                if (ModelState.IsValid)
                {
                    db.Employees.Add(employee);
                    await db.SaveChangesAsync();
                    return RedirectToAction("Index");
                }
    
                return View(employee);
            }
    
            // GET: /Employee/Edit/5
            public async Task Edit(int? id)
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Employee employee = await db.Employees.FindAsync(id);
                if (employee == null)
                {
                    return HttpNotFound();
                }
                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 async Task Edit([Bind(Include="Id,Name,NickName,Designation,Dept")] Employee employee)
            {
                if (ModelState.IsValid)
                {
                    db.Entry(employee).State = EntityState.Modified;
                    await db.SaveChangesAsync();
                    return RedirectToAction("Index");
                }
                return View(employee);
            }
    
            // GET: /Employee/Delete/5
            public async Task Delete(int? id)
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Employee employee = await db.Employees.FindAsync(id);
                if (employee == null)
                {
                    return HttpNotFound();
                }
                return View(employee);
            }
    
            // POST: /Employee/Delete/5
            [HttpPost, ActionName("Delete")]
            [ValidateAntiForgeryToken]
            public async Task DeleteConfirmed(int id)
            {
                Employee employee = await db.Employees.FindAsync(id);
                db.Employees.Remove(employee);
                await db.SaveChangesAsync();
                return RedirectToAction("Index");
            }
    
            protected override void Dispose(bool disposing)
            {
                if (disposing)
                {
                    db.Dispose();
                }
                base.Dispose(disposing);
            }
        }
    
    

    Step 7: Views – After selecting and executing template views are automatically created. Here is the views for CRUD operation of Employee.

    Create.cshtml

    
    @model MVCAsync.Models.Employee
    
    
    
    
    
        
        Create
    
    
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/jqueryval")
        
        
        @using (Html.BeginForm()) 
        {
            @Html.AntiForgeryToken()
            
            

    Employee


    @Html.ValidationSummary(true)
    @Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.Name) @Html.ValidationMessageFor(model => model.Name)
    @Html.LabelFor(model => model.NickName, new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.NickName) @Html.ValidationMessageFor(model => model.NickName)
    @Html.LabelFor(model => model.Designation, new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.Designation) @Html.ValidationMessageFor(model => model.Designation)
    @Html.LabelFor(model => model.Dept, new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.Dept) @Html.ValidationMessageFor(model => model.Dept)
    }
    @Html.ActionLink("Back to List", "Index")

    Delete.cshtml

    @model MVCAsync.Models.Employee
    
    
    
    
    
    
        
        Delete
    
    
        

    Are you sure you want to delete this?

    Employee


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

    Details.cshtml

    @model MVCAsync.Models.Employee
    
    
    
    
    
        
        Details
    
    
        

    Employee


    @Html.DisplayNameFor(model => model.Name)
    @Html.DisplayFor(model => model.Name)
    @Html.DisplayNameFor(model => model.NickName)
    @Html.DisplayFor(model => model.NickName)
    @Html.DisplayNameFor(model => model.Designation)
    @Html.DisplayFor(model => model.Designation)
    @Html.DisplayNameFor(model => model.Dept)
    @Html.DisplayFor(model => model.Dept)

    @Html.ActionLink("Edit", "Edit", new { id = Model.Id }) | @Html.ActionLink("Back to List", "Index")

    Edit.cshtml

    @model MVCAsync.Models.Employee
    
    
    
    
    
    
        
        Edit
    
    
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/jqueryval")
        
        
        @using (Html.BeginForm())
        {
            @Html.AntiForgeryToken()
            
            

    Employee


    @Html.ValidationSummary(true) @Html.HiddenFor(model => model.Id)
    @Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.Name) @Html.ValidationMessageFor(model => model.Name)
    @Html.LabelFor(model => model.NickName, new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.NickName) @Html.ValidationMessageFor(model => model.NickName)
    @Html.LabelFor(model => model.Designation, new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.Designation) @Html.ValidationMessageFor(model => model.Designation)
    @Html.LabelFor(model => model.Dept, new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.Dept) @Html.ValidationMessageFor(model => model.Dept)
    }
    @Html.ActionLink("Back to List", "Index")

    Index.cshtml

    @model IEnumerable
    
    
    
    
    
        
        Index
    
    
        

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

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

    Step 8: Add a link to _Layout page to access Employee information in Views/Shared

        		
    

    Step 9: Run the following command in package manager console one after another

    PM> Enable-Migrations -ContextTypeName EmployeeDBContext
    PM> Add-Migration created
    PM> Update-Database –Verbose

    Now run application and apply CRUD operation on it. It’s simple!!

    Output:

    03