Building a CRUD using MVC 4 using Repository pattern as the model - Step by step

Niladri.Biswas
Posted by in ASP.NET MVC category on for Beginner level | Points: 250 | Views : 77219 red flag

In this article we will build a CRUD operation using MVC 4 using Repository pattern as the model.


 Download source code for Building a CRUD using MVC 4 using Repository pattern as the model - Step by step

Introduction

In this article we will build a CRUD operation using MVC 4 using Repository pattern as the model.We will demonstrate our article with an employee information.

Straight to Experiment

Fire up visual studio and choose "ASP.NET MVC 4 Web Application".

Choose "Internet Application" and keep "Razor" view engine.

Now let us first define the model

Let us create a Employee.cs file and add the below properties

namespace MvcApplication1.Models
{
    public class Employee
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public int Salary { get; set; }
    }
}

Next create an interface by the name IEmployeeRepository.cs and add the below methods

using System.Collections.Generic;
namespace MvcApplication1.Models
{
    interface IEmployeeRepository
    {
        IEnumerable<Employee> GetAll();
        Employee Get(int EmployeeId);
        Employee Add(Employee item);
        bool Update(Employee item);
        bool Delete(int EmployeeId);
    }
}

Next add a concrete EmployeeREpository.cs file as under

using System;
using System.Collections.Generic;

namespace MvcApplication1.Models
{
    public class EmployeeRepository:IEmployeeRepository
    {
        private List<Employee> employees = new List<Employee>();
        private int _nextId = 1;


        public EmployeeRepository()
        {
            // Add employees
            Add(new Employee { Name = "Rama Karan", Age=24, Salary=5000 });
            Add(new Employee { Name = "Anup Dhawan", Age = 27, Salary = 8000 });
        }

        public IEnumerable<Employee> GetAll()
        {
            return employees;
        }

        public Employee Get(int EmployeeId)
        {           
            return employees.Find(p => p.EmployeeId == EmployeeId);
        }

        public Employee Add(Employee employee)
        {
            if (employee == null)
            {
                throw new ArgumentNullException("no employee to add");
            }
           
            employee.EmployeeId = _nextId++;
            employees.Add(employee);

            return employee;
        }

        public bool Update(Employee employee)
        {
            if (employee == null)
            {
                throw new ArgumentNullException("no employee to update");
            }
           
            int index = employees.FindIndex(p => p.EmployeeId == employee.EmployeeId);
            if (index == -1)
            {
                return false;
            }
            employees.RemoveAt(index);
            employees.Insert(index, employee);

            return true;
        }

        public bool Delete(int EmployeeId)
        {  
            employees.RemoveAll(p => p.EmployeeId == EmployeeId);

            return true;
        }
    }
}

So the model will look as under

Let us create the controller and the views simultaneously.Since it is a CRUD operation , so there will be four actions/operations and henceforth four views should be created ideally viz. Create( or Insert action/operation), Index(or READ action/operation),Edit(or Update action/operation) and Delete(Delete action/operation).Along with all these we will have a single item display which will be name as Details.

The View will look as under

Now let us create an EmployeeController.cs file

Let us create the Index View as under

For activation of the Index View(Index.cshtml), let us write the below code in the EmployeeController

static readonly IEmployeeRepository repository = new EmployeeRepository();

//
// GET: /Employee/

public ActionResult Index()
{
	return View(repository.GetAll().ToList());
}

And update the Index View(Index.cshtml) as under

@model IEnumerable<MvcApplication1.Models.Employee>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.EmployeeId)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Age)
        </th> 
        <th>
            @Html.DisplayNameFor(model => model.Salary)
        </th>        
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.EmployeeId)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Age)
        </td>
        <th>
            @Html.DisplayNameFor(model => model.Salary)
        </th>         
        <td>
            @Html.ActionLink("Edit", "Edit", new { item.EmployeeId }) |
            @Html.ActionLink("Details", "Details", new {item.EmployeeId }) |
            @Html.ActionLink("Delete", "Delete", new { item.EmployeeId })
        </td>
    </tr>
}

</table>

Intially we are setting the model data

@model IEnumerable<MvcApplication1.Models.Employee>

We are creating a new link call "Create New"(it's use will be reveal later).

<p>
    @Html.ActionLink("Create New", "Create")
</p>

The first argument is the name of the hyperlink while the second(i.e. "Create") is the name of the action(yet to be define in the controller).

Next we are creating the table heading as under

<tr>
        <th>
            @Html.DisplayNameFor(model => model.EmployeeId)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Age)
        </th> 
        <th>
            @Html.DisplayNameFor(model => model.Salary)
        </th>        
        <th></th>
    </tr>

Finally we are setting the data inside the "foreach" loop

@foreach (var employee in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => employee.EmployeeId)
        </td>
        <td>
            @Html.DisplayFor(modelItem => employee.Name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => employee.Age)
        </td>
        <th>
            @Html.DisplayFor(modelItem => employee.Salary)
        </th>         
        <td>
            @Html.ActionLink("Edit", "Edit", new { employee.EmployeeId }) |
            @Html.ActionLink("Details", "Details", new {employee.EmployeeId }) |
            @Html.ActionLink("Delete", "Delete", new { employee.EmployeeId })
        </td>
    </tr>
}

Now visit inside the "App_Start" and in the RouteConfig.cs file change the below

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 = "Index", id = UrlParameter.Optional }
		);
	}
}

Now let us run the application and the output will be as under

Next add a "Create" View(Create.chtml) and add the below code

@model MvcApplication1.Models.Employee

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>


@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Products</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.EmployeeId)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.EmployeeId)
            @Html.ValidationMessageFor(model => model.EmployeeId)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Age)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Age)
            @Html.ValidationMessageFor(model => model.Age)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Salary)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Salary)
            @Html.ValidationMessageFor(model => model.Salary)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

In the controller add the below methods

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

//
// Insert:Create
[HttpPost]
public ActionResult Create(Employee employee)
{
	if (ModelState.IsValid)
	{
		employee = repository.Add(employee);
		return RedirectToAction("Index");
	}

	return View(employee);
}

The first method will activate the "Create" link when the "Create New" link will be clicked.

When the user will fill up the records and click on the "Create button

then the public ActionResult Create(Employee employee) will be initiated, the record will be added and finally the control will be returned to the "Index" action method.

Now let us create the Details View("Details.chtml") as under

 @model MvcApplication1.Models.Employee

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

<fieldset>
    <legend>Employee Details</legend>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.EmployeeId)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.EmployeeId)
    </div>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.Name)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Name)
    </div>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.Age)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Age)
    </div>  
    
    <div class="display-label">
         @Html.DisplayNameFor(model => model.Salary)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Salary)
    </div>
      
</fieldset>
<p>
    @Html.ActionLink("Edit", "Edit", new { Model.EmployeeId  }) |
    @Html.ActionLink("Back to List", "Index")
</p>

The corresponding action will be

public ActionResult Details(int EmployeeId = 0)
{
	var employee = repository.Get(EmployeeId);
	if (employee == null)
	{
		return HttpNotFound();
	}
	return View(employee);
}

For Edit View("Edit.chtml"), we have the below

 @model MvcApplication1.Models.Employee

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Employee Details</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.EmployeeId)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.EmployeeId)
            @Html.ValidationMessageFor(model => model.EmployeeId)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Age)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Age)
            @Html.ValidationMessageFor(model => model.Age)
        </div>

        <div class="display-label">
         @Html.LabelFor(model => model.Salary)
        </div>
        <div class="display-field">
             @Html.EditorFor(model => model.Salary)
            @Html.ValidationMessageFor(model => model.Salary)
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

The corresponding action will be

public ActionResult Edit(int EmployeeId = 0)
{
	var employee = repository.Get(EmployeeId);
	if (employee == null)
	{
		return HttpNotFound();
	}
	return View(employee);
}

//POST
[HttpPost]
public ActionResult Edit(Employee employee)
{
	if (ModelState.IsValid)
	{
		repository.Update(employee);
		return RedirectToAction("Index");
	}
	return View(employee);
}
 

The first action public ActionResult Edit(int EmployeeId = 0) is used for displaying the item on the Edit screen

The second action public ActionResult Edit(Employee employee) is used when the changed item is saved by clicking on the "Save" button

Finally the result is as under

For Delete View("Delete.chtml"), we have the below

 @model MvcApplication1.Models.Employee

@{
    ViewBag.Title = "Delete";
}

<h2>Delete</h2>

<h3>Are you sure you want to delete this?</h3>
<fieldset>
    <legend>Employee Details</legend>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.EmployeeId)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.EmployeeId)
    </div>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.Name)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Name)
    </div>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.Age)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Age)
    </div>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.Salary)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Salary)
    </div>
    
</fieldset>
@using (Html.BeginForm()) {
    <p>
        <input type="submit" value="Delete" /> |
        @Html.ActionLink("Back to List", "Index")
    </p>
}

And the actions are

public ActionResult Delete(int EmployeeId = 0)
{
	 var employee = repository.Get(EmployeeId);
	 if (employee == null)
	{
		return HttpNotFound();
	}
	 return View(employee);
}

[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int EmployeeId)
{
	repository.Delete(EmployeeId);
	return RedirectToAction("Index");
}

Clicking on the "Delete" link takes us to the confirmation page

And clicking on the Delete button, deletes the record

Conclusion

This ends the journey.Hope this will be useful.Thanks for reading.Zipped file is attached herewith.

Page copy protected against web site content infringement by Copyscape

About the Author

Niladri.Biswas
Full Name: Niladri Biswas
Member Level: Platinum
Member Status: Member
Member Since: 10/25/2010 11:04:24 AM
Country: India
Best Regards, Niladri Biswas
http://www.dotnetfunda.com
Technical Lead at HCL Technologies

Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)