Memorable last day with my trainees(1st Batch, C#.NET Applied OOP)


Memorable last day with my trainees(1st Batch, C#.NET Applied OOP)at LEADS Technology Limited

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