MVC Crud Using Generic Repository And jQuery

Background

It’s good idea to stay on the same page while performing create, update, and delete operations. There are many ways to do it such as making them partial views, using Bootstrap’s model popup, loading partial views, using AJAX etc. However, In this post, we will learn how to do it, using jQuery, Generic Repository Pattern, and Entity Framework code first migration.

Repository Pattern

Repository mediates between the domain and the data mapping layers, using a collection-like interface to access the domain objects. (Edward Hieatt and Rob Mee).

Mvc

Getting started,

Step 1 Create MVC Application

Open Visual Studio to create a new project, followed by selecting ASP.NET Web Application and name mvc_crud and click OK. In the templatesSelectMvc template and keep the authentication off.

Mvc

Step 2

Install Entity Framework and fluent validation through NuGet Package.

Step 3 Add Model Class

Now, add new class under models and name it as employee class.
  1. namespacemvc_CRUD.Models {  
  2.     publicclassEmployee {  
  3.         publicint Id {  
  4.             get;  
  5.             set;  
  6.         }  
  7.         publicstring Phone {  
  8.             get;  
  9.             set;  
  10.         }  
  11.         publicstringFirstName {  
  12.             get;  
  13.             set;  
  14.         }  
  15.         publicstringLastName {  
  16.             get;  
  17.             set;  
  18.         }  
  19.         publicstring Email {  
  20.             get;  
  21.             set;  
  22.         }  
  23.         publicDepartmentDepartment {  
  24.             get;  
  25.             set;  
  26.         }  
  27.         publicGenderGender {  
  28.             get;  
  29.             set;  
  30.         }  
  31.         publicboolIsActive {  
  32.             get;  
  33.             set;  
  34.         }  
  35.     }  
  36. }  
  37. publicenumDepartment {  
  38.     Sales,  
  39.     Management,  
  40.     Security  
  41. }  
  42. publicenumGender {  
  43.     Male,  
  44.     Female  
  45. }  
Step 4 Create validation class

Create new folder validation. Afterwards, right click on validation folder and add new class, name it EmployeeValidation.
  1. publicclassEmployeeValidation AbstractValidator < Employee > {  
  2.     publicEmployeeValidation() {  
  3.         RuleFor(e => e.FirstName).NotEmpty().Length(0, 8);  
  4.         RuleFor(e => e.LastName).NotEmpty().Length(0, 8);  
  5.         RuleFor(e => e.Phone).Length(10).WithMessage("Enter valid number");  
  6.         RuleFor(s => s.Email).NotEmpty().WithMessage("Email address is required").EmailAddress().WithMessage("A valid email is required");  
  7.     }  
  8. }  
Step 5 Create DbContext class

Now, let’s create a new folder, DAL. Afterwards, add new class, which is derived from DbContext and name it EmployeeContext.
  1. publicclassEmployeeContext DbContext {  
  2.     publicEmployeeContext()  
  3.     base("EmployeeDB") {}  
  4.     publicDbSet < Employee > Empoyees {  
  5.         get;  
  6.         set;  
  7.     }  
  8. }  
Step 6 Create Repository Interface class

Now, let’s add a new generic interface, IRepositoryunder abstract folder .
  1. publicinterfaceIRepository < T > whereT class {  
  2.     IEnumerable < T > GetAll();  
  3.     TFindBy(object id);  
  4.     void Add(Tobj);  
  5.     void Update(Tobj);  
  6.     void Delete(object id);  
  7.     void Save();  
  8. }  
Step 7 Create Repository Base class

Now, we are going to add an abstract class RepositoryBase, which has virtual implementation on IRepositary interface. For every other Repository, we will add later, which will inherit this abstract class by overriding the virtual methods.
  1. publicabstractclassRepositoryBase < T > whereT class {  
  2.     protectedEmployeeContext _context;  
  3.     protectedDbSet < T > dbSet;  
  4.     publicRepositoryBase() {  
  5.         this._context = newEmployeeContext();  
  6.         dbSet = _context.Set < T > ();  
  7.     }  
  8.     publicRepositoryBase(EmployeeContext _dataContext) {  
  9.         this._context = _dataContext;  
  10.         dbSet = _dataContext.Set < T > ();  
  11.     }  
  12.     publicvirtualIEnumerable < T > GetAll() {  
  13.         returndbSet.ToList();  
  14.     }  
  15.     publicTFindBy(object id) {  
  16.         returndbSet.Find(id);  
  17.     }  
  18.     publicvirtualvoid Add(Tobj) {  
  19.         dbSet.Add(obj);  
  20.     }  
  21.     publicvirtualvoid Update(Tobj) {  
  22.         dbSet.Attach(obj);  
  23.         _context.Entry(obj).State = EntityState.Modified;  
  24.     }  
  25.     publicvirtualvoid Delete(object id) {  
  26.         T existing = dbSet.Find(id);  
  27.         dbSet.Remove(existing);  
  28.     }  
  29.     publicvirtualvoid Save() {  
  30.         _context.SaveChanges();  
  31.     }  
  32. }  
Step 8 Create Repository class

Now, let’s create a new folder repository. Afterwards, add new class EmployeeRepository class, which will inherit from Abstract but with a generic repository base andIEmployeeRepository interface.
  1. namespacemvc_CRUD.Repository {  
  2.     publicclassEmployeeRepository RepositoryBase < Employee > , IEmployeeRepository {}  
  3.     publicinterfaceIEmployeeRepository IRepository < Employee > {}  
  4. }  
Step 9 Add connection string

Now, add the connection string in web.config file.
  1. <connectionStrings>  
  2.     <addname="EmployeeDB" connectionString="Data Source=.\SQLEXPRESS;InitialCatalog=EmployeeDB;Integrated Security=True;MultipleActiveResultSets=true" providerName="System.Data.SqlClient" /> </connectionStrings>  
Step 10
 
In the packet manager console, run the commands given below.

enable-migrations

add-migration "initial-migration"

update-database -verbose


Step 11 Add Controller class

Now, let’s EditHomeController and add the code given below. 
  1. publicclassHomeController Controller {  
  2.     publicreadonlyIEmployeeRepository _employeeRepository;  
  3.     publicHomeController(IEmployeeRepository _employeeRepository) {  
  4.         this._employeeRepository = _employeeRepository;  
  5.     }  
  6.     publicActionResult Index() {  
  7.         varemp = _employeeRepository.GetAll();  
  8.         return View(emp);  
  9.     }  
  10.     publicActionResult Create() {  
  11.             return View();  
  12.         }  
  13.         [HttpPost]  
  14.     publicActionResult Create(Employeeobj) {  
  15.             EmployeeValidationval = newEmployeeValidation();  
  16.             ValidationResult model = val.Validate(obj);  
  17.             if (model.IsValid) {  
  18.                 _employeeRepository.Add(obj);  
  19.                 _employeeRepository.Save();  
  20.             } else {  
  21.                 foreach(ValidationFailure _error inmodel.Errors) {  
  22.                     ModelState.AddModelError(_error.PropertyName, _error.ErrorMessage);  
  23.                 }  
  24.             }  
  25.             return View(obj);  
  26.         }  
  27.         // GET Employees/Edit/5  
  28.     publicActionResult Update(int id) {  
  29.             varemp = _employeeRepository.FindBy(id);  
  30.             return View(emp);  
  31.         }  
  32.         [HttpPost]  
  33.         [ValidateAntiForgeryToken]  
  34.     publicActionResult Update(Employeeemp) {  
  35.             if (ModelState.IsValid) {  
  36.                 _employeeRepository.Update(emp);  
  37.                 _employeeRepository.Save();  
  38.                 returnRedirectToAction("Index");  
  39.             }  
  40.             return View(emp);  
  41.         }  
  42.         // GET Employees/Delete/5  
  43.     publicActionResult Delete(int id) {  
  44.             varemp = _employeeRepository.FindBy(id);  
  45.             return View(emp);  
  46.         }  
  47.         [HttpPost, ActionName("Delete")]  
  48.         [ValidateAntiForgeryToken]  
  49.     publicActionResultDeleteConfirmed(int id) {  
  50.         _employeeRepository.Delete(id);  
  51.         _employeeRepository.Save();  
  52.         returnRedirectToAction("Index");  
  53.     }  
  54. }  
Step 12 Add Dependency Container

Before we generate views, let’s add a Dependency container. Install UnityMvc5 through NuGet Package and edit the unityConfig class in the App_Start folder.
  1. publicstaticclassUnityConfig {  
  2.     publicstaticvoidRegisterComponents() {  
  3.         var container = newUnityContainer();  
  4.         // register all your components with the container here  
  5.         // it is NOT necessary to register your controllers  
  6.         // e.g. container.RegisterType<ITestService, TestService>();  
  7.         container.RegisterType < IEmployeeRepository, EmployeeRepository > ();  
  8.         DependencyResolver.SetResolver(newUnityDependencyResolver(container));  
  9.     }  
  10. }  
Register in the global.asax file
  1. UnityConfig.RegisterComponents();  
Step 13 Add Index view

Now, let’s add Index view. Right click inside the action method and then click add view, followed by selecting the create strongly-typed view.

We will use the index to load the other pages, using jQuery but before it, lets get jqueryreveal. Here, we need the jqueryreveal.js and reveal.css files to render in the layout. Afterwards, add the create, update, and delete views.
  1. @model IEnumerable<mvc_CRUD.Models.Employee>  
  2. @{  
  3.     ViewBag.Title = "Index";  
  4. }  
  5. <div id="main_div" class="panel panel-primary">  <div class="panel-heading">Employee List</div>  
  6.     <div class="panel-body">  
  7.         <div class="col-md-6"><a href="#" data-reveal-id="Create" class="CreateBtn"><i class="glyphicon glyphicon-file">Add</i></a><br />         </div>  
  8.         <div class="table table-responsive">  
  9.             <table class="table table-striped table-condensed flip-content">  
  10.                 <thead class="flip-content">  
  11.                     <tr>  
  12.                         <th>Phone</th>  
  13.                         <th>First name</th>  
  14.                         <th>Last name</th>  
  15.                         <th>Email</th>  
  16.                         <th>Department</th>  
  17.                         <th>Gender</th>  
  18.                         <th>Is Active</th>  
  19.                         <th></th>  
  20.                     </tr>  
  21.                 </thead>  
  22.                 <tbody>  
  23.                     @foreach (var item in Model)  
  24.                     {  
  25.                        <tr>  
  26.                             <td> @Html.DisplayFor(modelItem => item.Phone) </td>  
  27.                             <td> @Html.DisplayFor(modelItem => item.FirstName) </td>  
  28.                             <td> @Html.DisplayFor(modelItem => item.LastName) </td>  
  29.                             <td> @Html.DisplayFor(modelItem => item.Email)</td>  
  30.                             <td>@Html.DisplayFor(modelItem => item.Department) </td>  
  31.                             <td> @Html.DisplayFor(modelItem => item.Gender) </td>  
  32.                             <td> @Html.DisplayFor(modelItem => item.IsActive)</td>  
  33.                          <td>  
  34.                       <a href="#" id="@item.Id" data-reveal-id="Update" class="UpdateBtn"><i class="glyphicon glyphicon-edit"></i</a>  
  35.                       <a href="#" id="@item.Id" data-reveal-id="Delete" class="DeleteBtn"><i class="glyphicon glyphicon-remove"></i></a>  
  36.                         </td>  
  37.                      </tr>  
  38.                     }  
  39.                 </tbody>  
  40.             </table>  
  41.         </div>  
  42.     </div>  
  43. </div>  
  44. <div id="Update" class="reveal-modal"></div>  
  45. <div id="Delete" class="reveal-modal"></div>  
  46. <a href="#" id="Create" class="reveal-modal"></a>  
  Add the following  jQuery in the script section at the bottom of the index view to load other views.
  1. @section Scripts{  
  2.     <script type="text/javascript">  
  3.         $(document).ready(function () {  
  4.             $('.UpdateBtn').click(function () {  
  5.                 var url = '@Url.Action("Update","Home")';  
  6.                 url = url + "?Id=" + this.id;  
  7.                 $('#Update').load(url);  
  8.             });  
  9.         });  
  10.     </script>  
  11.     <script type="text/javascript">  
  12.         $(document).ready(function () {  
  13.             $('.DeleteBtn').click(function () {  
  14.                 var url = '@Url.Action("Delete","Home")';  
  15.                 url = url + "?Id=" + this.id;  
  16.                 $('#Delete').load(url);  
  17.             });  
  18.         });  
  19.     </script>  
  20.     <script type="text/javascript">  
  21.         $(document).ready(function () {  
  22.             $('.CreateBtn').click(function () {  
  23.                 var url = '@Url.Action("Create","Home")';  
  24.                 $('#Create').load(url);  
  25.             });  
  26.         });  
  27.     </script>  
  28. }  
Step 14
 
Now, run the application.

Mvc

Update view

Mvc

Delete view

Mvc

Summary

Thank you so much for your reading. I hope the article is useful for all the readers. If you have any complaint or suggestion about the code or the article, please let me know. Don't forget to leave your opinion in the comments section bellow.