Building A Simple Application Using ASP.NET Core 1.0

9 minute read

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 have used following tools and technology to develop the project –

  • Visual Studio 2015 Update 3
  • Visual C#
  • ASP.NET MVC
  • Entity Framework core 1.0
  • Razor view engine
  • JQuery

Step 1: Create an ASP.net MVC Project

  • File -> New project and select the project template C# -> .NET Core -> Console application (.NET Core).

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

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<Employee> 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<Employee> 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<ApplicationUser>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
 
        public DbSet<Dept> Depts { get; set; }
        public DbSet<Designation> Designations { get; set; }
        public DbSet<Employee> 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.

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

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.

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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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
 
        /// <summary>
        /// This is a workaround for missing seed data functionality in EF 7.0-rc1
        /// More info: https://github.com/aspnet/EntityFramework/issues/629
        /// </summary>
        /// <param name="app">
        /// An instance that provides the mechanisms to get instance of the database context.
        /// </param>
        public static void SeedData(this IApplicationBuilder app)
        {
            var db = app.ApplicationServices.GetService<ApplicationDbContext>();
 
            // 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<Employee>()
            {
                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<Dept> lstDept = new List<Dept> {
                     new Dept { Name = "Supply Chain" },
                     new Dept { Name = "Software Innovation" }
                };
 
            List<Designation> lstDesignation = new List<Designation>
            {
                    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();
        }
    }
}

Step 9: Add SeedData Method

  • Add SeedData method in Startup class as follows.
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<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
 
            services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();
 
            services.AddMvc();
 
            // Add application services.
            services.AddTransient<IEmailSender, AuthMessageSender>();
            services.AddTransient<ISmsSender, AuthMessageSender>();
        }
 
        // 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
    PM> Update-Database -Verbose
    

    Step 10: Add Links in Layout Page
    Add Dept and Employee link as follows. ```csharp

  • 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.