Saturday, December 24, 2016

Mvc CRUD using generic Repository and jQuery

In this article you will learn how to create simple crud operation using generic repository pattern  and jQuery.
      

Background

It’s good idea  to let  stay on the same page while performing  create update and delete operations,  there are many ways to do that such as making them as partial views, using bootstrap’s model popup,  loading partial views, using ajax etc. However  In this post we will learn how to do that using jQuery, generic repository pattern and  Entity frame work code first migration.

Repository pattern

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



Getting Started

Step 1:  Create Mvc  application
Open visual Studio to create new project  then select Asp.net web application and name mvc_crud then click Ok. In the templates Select Mvc template and keep the authentication off



Step 2: Install Entity Framework and Fluent Validation through nugget Package.

Step 3: Add Model Class

Next  add new class under  models and name it as employee class.

namespace mvc_CRUD.Models
{
    public class Employee
    {
        public int Id { get; set; }
        public string Phone { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public Department Department { get; set; }
        public Gender Gender { get; set; }
        public bool IsActive { get; set; }
    }
}

  public enum Department
{
    Sales,
    Management,
    Security
}

public enum Gender
{
    Male,
    Female
}

Step 4:  Create validation class

 Create new folder validation after that right click validation folder and add new class , name it as EmployeeValidation .

 public class EmployeeValidation : AbstractValidator<Employee>
    {
        public EmployeeValidation()
        {
            RuleFor(e => e.FirstName).NotEmpty().Length(0, 8);
            RuleFor(e => e.LastName).NotEmpty().Length(0, 8);
            RuleFor(e => e.Phone).Length(10).WithMessage("Enter valid number");
            RuleFor(s => s.Email).NotEmpty().WithMessage("Email address is required")
                    .EmailAddress().WithMessage("A valid email is required");
        }
    }


Step 5:  Create DbContext class

Next create new folder DAL, after that add new class that's derived from DbContext and name it  EmployeeContext.

 public class EmployeeContext :DbContext
    {
        public EmployeeContext()
            : base("EmployeeDB") { }
        public DbSet<Employee> Empoyees { get; set; }
    }



Step 6: Create Repository Interface class

Now let’s add new generic interface IRepository under  abstract  folder .

 public interface IRepository<T> where T: class
    {
        IEnumerable<T> GetAll();
        T FindBy(object id);
        void Add(T obj);
        void Update(T obj);
        void Delete(object id);
        void Save();
    }

Step 7: Create Repository Base class

 Next we are going to Add an abstract class RepositoryBase that has virtual implementation on IRepositary interface. So every other repository we will add later will inherit this abstract class by overriding the virtual methods.

 public abstract class RepositoryBase<T> where T: class
    {
        protected EmployeeContext _context;
        protected DbSet<T> dbSet ;

        public RepositoryBase()
        {
            this._context = new EmployeeContext();
            dbSet = _context.Set<T>();
        }

        public RepositoryBase(EmployeeContext _dataContext)
        {
            this._context = _dataContext;
            dbSet = _dataContext.Set<T>();
        }
        public virtual IEnumerable<T> GetAll()
        {
            return dbSet.ToList();
        }

      public T  FindBy(object id)
        {
            return dbSet.Find(id);
        }

        public virtual void Add(T obj)
        {
            dbSet.Add(obj);
        }

        public virtual void Update(T obj)
        {
            dbSet.Attach(obj);
            _context.Entry(obj).State = EntityState.Modified;
        }

        public virtual void Delete(object id)
        {
            T existing = dbSet.Find(id);
            dbSet.Remove(existing);
        }

        public virtual void Save()
        {
                _context.SaveChanges();
        }
    }


Step 8: Create Repository class

 Create new folder repository, after that add new class EmployeeRepository class that inherit from Abstract but generic repository base  and IEmployeeRepository interface. 

namespace mvc_CRUD.Repository
{
    public class EmployeeRepository: RepositoryBase<Employee>, IEmployeeRepository{}

    public interface IEmployeeRepository: IRepository<Employee>{}
}

Step 9:  Add Connection string

Next  add connection string  in web.config file .

  <connectionStrings>
    <add name="EmployeeDB" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=EmployeeDB;Integrated Security=True;MultipleActiveResultSets=true" providerName="System.Data.SqlClient" />
  </connectionStrings>



Step 10: in the package manager console run the following commands

enable-migrations
add - migration "initial-migration"
update - database - verbose

Step 11:  Add Controller class

Now let’s  Edit HomeController and add the following code:

 public class HomeController : Controller
    {
        public readonly IEmployeeRepository _employeeRepository;
        
        public HomeController(IEmployeeRepository _employeeRepository)
        {
            this._employeeRepository = _employeeRepository;
        }

        public ActionResult Index()
        {
            var emp = _employeeRepository.GetAll();
            return View(emp);
        }

        public ActionResult Create()
        {
            return View();
        }
        [HttpPost]
        public ActionResult Create(Employee obj)
        {
            EmployeeValidation val = new EmployeeValidation();
            ValidationResult model = val.Validate(obj);
            if (model.IsValid)
            {
                _employeeRepository.Add(obj);
                _employeeRepository.Save();
            }
            else
            {
                foreach (ValidationFailure _error in model.Errors)
                {
                    ModelState.AddModelError(_error.PropertyName, _error.ErrorMessage);
                }
            }
            return View(obj);

        }
        // GET: Visitors/Edit/5
        public ActionResult Update(int id)
        {
            var emp = _employeeRepository.FindBy(id);
            return View(emp);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Update(Employee emp)
        {
            if (ModelState.IsValid)
            {
                _employeeRepository.Update(emp);
                _employeeRepository.Save();
                return RedirectToAction("Index");
            }
            return View(emp);
        }

        // GET: Visitors/Delete/5
        public ActionResult Delete(int id)
        {
            var emp = _employeeRepository.FindBy(id);
            return View(emp);
        }

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            _employeeRepository.Delete(id);
            _employeeRepository.Save();
            return RedirectToAction("Index");
        }
    }

Step 12: Add Dependency Container
Before we generate views let’s add Dependency container, Install UnityMvc5 through nugget package and edit the  unityConfig class in the App_Start folder.

  
 public static class UnityConfig
    {
        public static void RegisterComponents()
        {
            var container = new UnityContainer();

            // register all your components with the container here
            // it is NOT necessary to register your controllers

            // e.g. container.RegisterType<ITestService, TestService>();
            container.RegisterType<IEmployeeRepository, EmployeeRepository>();
            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        }
    }

a         And Register  in the global.asax file 


  UnityConfig.RegisterComponents();
'
Step 14:  Add Index view
Now let’s add Index view, right click inside the action method and then click add view and select the create strongly-typed view.

We will use index to load the other pages using Jquery but before that lets get jqueryreveal from Here, we  need the jqueryreveal.js  and reveal.css files to render in the layout. After that add the create, update,and delete views. 

@model IEnumerable<mvc_CRUD.Models.Employee>

@{
    ViewBag.Title = "Index";
}
<div id="main_div" class="panel panel-primary">

    <div class="panel-heading">Employee List</div>
    <div class="panel-body">
        <div class="col-md-6">
            <a href="#" data-reveal-id="Create" class="CreateBtn"><i class="glyphicon glyphicon-file">Add</i></a><br />
        </div>

        <div class="table table-responsive">
            <table class="table table-striped table-condensed flip-content">
                <thead class="flip-content">
                    <tr>
                        <th>Phone</th>
                        <th>First name</th>
                        <th>Last name</th>
                        <th>Email</th>
                        <th>Department</th>
                        <th>Gender</th>
                        <th>Is Active</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var item in Model)
                    {
                        <tr>
                            <td> @Html.DisplayFor(modelItem => item.Phone) </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.FirstName)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.LastName)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.Email)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.Department)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.Gender)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.IsActive)
                            </td>

                            <td>
                                <a href="#" id="@item.Id" data-reveal-id="Update" class="UpdateBtn"><i class="glyphicon glyphicon-edit"></i></a>
                                <a href="#" id="@item.Id" data-reveal-id="Delete" class="DeleteBtn"><i class="glyphicon glyphicon-remove"></i></a>
                            </td>

                        </tr>
                    }
                </tbody>
            </table>
        </div>
    </div>
</div>
<div id="Update" class="reveal-modal">

</div>
<div id="Delete" class="reveal-modal">

</div>
<a href="#" id="Create" class="reveal-modal">

</a>


@section Scripts{
    <script type="text/javascript">
        $(document).ready(function () {
            $('.UpdateBtn').click(function () {
                var url = '@Url.Action("Update","Home")';
                url = url + "?Id=" + this.id;
                $('#Update').load(url);
            });
        });
    </script>

    <script type="text/javascript">
        $(document).ready(function () {
            $('.DeleteBtn').click(function () {
                var url = '@Url.Action("Delete","Home")';
                url = url + "?Id=" + this.id;
                $('#Delete').load(url);
            });
        });
    </script>
    <script type="text/javascript">
        $(document).ready(function () {
            $('.CreateBtn').click(function () {
                var url = '@Url.Action("Create","Home")';
                $('#Create').load(url);
            });
        });
    </script>
}


Step 15  Now run the application .

Update view

Delete view

Conclusion

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

Download Source code 













0 comments:

Post a Comment