In this article, we’ll implement CRUD operations in Asp.Net MVC with jQuery Ajax Using JSON and Entity Framework.
You can download this project source code from here :
Application Demo :
Create Asp.Net MVC Project
First of all, let’s create an Asp.net MVC Project, Open your Visual Studio.
Go to File > New > Project ( Ctrl+Shift+N).
Then select MVC Template.
Now we have a brand new Asp.Net MVC Application. Before continuing with this project, let me create SQL Server database for this application.
Create a Database
I use Management Studio to create and manage SQL Server DB. A database with name ‘jQueryAjaxDB’ is created.
In this application, we’ll deal with details of employees. So an employee table is created using following SQL Script.
1 2 3 4 5 6 7 | CREATE TABLE [dbo].[Employee]( [EmployeeID] [int] IDENTITY(1,1) NOT NULL Primary Key, [Name] [varchar](50) NULL, [Position] [varchar](50) NULL, [Office] [varchar](50) NULL, [Salary] [int], [ImagePath] [varchar](500) NULL) |
That is enough for database part. Back to Visual Studio, then add ADO.NET Entity Data Model for the database.
Add Entity Model for Database
In-order to add Entity Model inside Models folder. Right click on Models Folder, Add > New Item. I have named this Entity Model as DBModels.
Select Generate from database.
In Entity Data Model Wizard, Click On New Connection.
Provide SQL Server instance details and then select the DB – jQueryAjaxDB.
As per previous Entity Data Model Wizard window, we’ll save DB Connection string in WebConfig as DBModel. After creating this Entity Model, there will be a class with this name ( DBModel ). We’ll create an object of this class in-order to interact with database.
From Entity Data Model Wizard, you will get following window, select tables that we want to add inside the Entity Model.
Click on Finish. Diagrammatic Representation of newly created EF Model looks like this.
Inside this DBModels.edmx, you can see a DBModels.Context.cs file for DBModel Class. we’ll create an object of this class to work with database.
DBModels.tt > Employee.cs contains Employee Class, which contains properties corresponding to SQL Table columns, So Employee class will be model class for this MVC application..
Add MVC Controller
Right click on Controllers folder, Add > Controller. Select Empty MVC Template, then name your controller as EmployeeController. Currently this Employee controller has one action method Index. In-order to implement CRUD Operations, we’ll add following action methods in Employee Controller.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public class EmployeeController : Controller { [HttpGet] public ActionResult Index() { ... } [HttpGet] public ActionResult ViewAll() { ... } [HttpGet] public ActionResult AddOrEdit(int id=0) { ... } [HttpPost] public ActionResult AddOrEdit(Employee emp) { ... } [HttpPost] public ActionResult Delete(int id) { ... } } |
- Index – Display other action method views using tab controller. Like Home/ Dashboard for the controller.
- ViewAll – Return an HTML table, to list records from Employee table.
- HttpGet AddOrEdit – Should return a view containing form for Insert and Update Operation. If the method parameter id is zero, we’ll return form for Insert Operation otherwise It will be form to update an employee with EmployeeID is equal to given id parameter.
- HttpPost AddOrEdit – Form returned from HttpGet AddOrEdit will be posted to this action method. Inside this action method, Insert Or Update Operation will be done based on EmployeeId inside emp object.
- HttpPost Delete – Used to Delete an employee record with given EmployeeID through id parameter.
I want to make the Employee controller as default controller, for that you can update RouteConfig as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 } ); } } |
Let’s Start the Design
By default, there is a global style sheet – Site.css inside Content folder. Added some additional CSS rules inside the file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | body { padding-top: 50px; padding-bottom: 20px; } /* Set padding to keep content from hitting the edges */ .body-content { padding-left: 15px; padding-right: 15px; } /* Set width on the form input elements since they're 100% wide by default */ input, select, textarea { max-width: 280px; } /* styles for validation helpers */ .field-validation-error { color: #b94a48; } .field-validation-valid { display: none; } input.input-validation-error { border: 1px solid #b94a48; } input[type="checkbox"].input-validation-error { border: 0 none; } .validation-summary-errors { color: #b94a48; } .validation-summary-valid { display: none; } ul.nav.nav-tabs { margin : 10px 0px; } ul.nav.nav-tabs li:not(.active) a { background-color: #eeeeee; color: grey; } ul.nav.nav-tabs li.active a { border-top: 3px solid #16a765; } .loaderbody { width: 100%; height: 100%; left: 0px; top: 0px; position : absolute; background-color:rgba(128,128,128,0.2); z-index : 2147483647; } .loader { border: 16px solid #f3f3f3; /* Light grey */ border-top: 16px solid #3498db; /* Blue */ border-radius: 50%; width: 120px; height: 120px; animation: spin 2s linear infinite; position : fixed; top : 45%; left : 40%; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } |
We have added a new JavaScript file Scripts.js inside Scripts folder. Apart from these we’ll use two jQuery plugins inside this application, they are and . Datatable plugin is used to add more useful functions to a normal HTML table. In-order to add NotifyJS Plugin, you can go to the plugin website – , then download minified java script file – notify.min.js. Add this script file inside Scripts folder. Later in this article, we’ll discuss how we can use these two plugins.
For an MVC Application, default layout page will be _Layout.cshtml (Inside /Views/Shared Folder). Made some changes to default nav bar and footer. Finally _Layout.cshtml file looks like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - My ASP.NET Application</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" /> </head> <body> <div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> @Html.ActionLink("Employee Register", "Index", "Employee", null, new { @class = "navbar-brand" }) </div> </div> </div> <div class="container body-content"> @RenderBody() <hr /> <footer> <p>jQuery ajax - Asp.Net MVC CRUD Operations</p> </footer> </div> <div class="loaderbody" id="loaderbody"> <div class="loader"></div> </div> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required: false) <script src="~/Scripts/Scripts.js"></script> <script src="~/Scripts/notify.min.js"></script> </body> </html> |
Added style sheet reference for Font-Awesome Icon in header part. Before body end tag, we have added script files for global JavaScript file Scripts.js and notify.min.js. Apart from these we have added a div for loading spinner to show during Server Side Operations.
1 2 3 | <div class="loaderbody" id="loaderbody"> <div class="loader"></div> </div> |
Later we’ll show and hide during jQuery Ajax server side request.
By defualt, jquery and boostrap bundles are added to this layout. All of these bundles are defined inside App_Start/BundleConfig.cs file.
Index Action Method
Inside Employee controller, we have an action method Index as follows
1 2 3 4 5 6 7 8 9 | public class EmployeeController : Controller { [HttpGet] public ActionResult Index() { return View(); } ... } |
Let’s add a view for this action method, right click inside the action method then select Add View. view name will be Index with Empty Template then check ‘Use a layout page’, Click on Add. Inside this view file we have used following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @{ ViewBag.Title = "Index"; } <ul class="nav nav-tabs"> <li><a data-toggle="tab" href="#firstTab">View All</a></li> <li class="active"><a data-toggle="tab" href="#secondTab">Add New</a></li> </ul> <div class="tab-content"> <div id="firstTab" class="tab-pane fade in">@Html.Action("ViewAll")</div> <div id="secondTab" class="tab-pane fade in active">@Html.Action("AddOrEdit")</div> </div> <link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet" /> @section scripts{ @Scripts.Render("~/bundles/jqueryval") <script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script> } |
By default, for this view _Layout.cshtml will be the layout page. Here we have used a Bootstrap tab control with two tabs. One for listing records from Employee table. Inside the second tab, we’ll show the form for Insert or Update operation.
Then we have jQuery Datatable stylesheet and script file reference. Script codes are added inside the scripts section, which is defined inside the layout page. Along with this script file, we have added jqueryval bundle for client side validation.
Let’s Update Employee Class
I have updated Employee model class, which was automatically created inside Entity Model.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public partial class Employee { public int EmployeeID { get; set; } [Required(ErrorMessage = "This field is required.")] public string Name { get; set; } public string Position { get; set; } public string Office { get; set; } public Nullable<int> Salary { get; set; } [DisplayName("Image")] public string ImagePath { get; set; } [NotMapped] public HttpPostedFileBase ImageUpload { get; set; } public Employee() { ImagePath = "~/AppFiles/Images/default.png"; } } |
Required attribute is added to Name property with an error message. An Extra Property ImageUpload of the type HttpPostedFileBase is added. It will use this for Image Upload.
Inside the constructor, we initialized ImagePath property with a default Image path. we have add an image default.png inside AppFiles > Images Folder ( these two folders are added to the solution explorer).
List Records from Employee Table
Inside the first Bootstrap tab, we’ll list records from Employee table using an HTML table with a help of ViewAll action method.
1 2 3 4 5 6 7 8 9 10 11 12 | public ActionResult ViewAll() { return View(GetAllEmployee()); } IEnumerable<Employee> GetAllEmployee() { using (DBModel db = new DBModel()) { return db.Employees.ToList<Employee>(); } } |
Here GetAllEmployee() function returns list of employee from Employee table. Now let’s create a view for this ViewAll action method – ViewAll.cshtml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | @model IEnumerable<jQueryAjaxInAsp.NETMVC.Models.Employee> @{ ViewBag.Title = "ViewAll"; Layout = null; } <table class="table table-striped table-condensed" id="employeeTable"> <thead> <tr> <th> @Html.DisplayNameFor(model => model.Name) </th> <th> @Html.DisplayNameFor(model => model.Position) </th> <th> @Html.DisplayNameFor(model => model.Office) </th> <th> @Html.DisplayNameFor(model => model.Salary) </th> <th></th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.Position) </td> <td> @Html.DisplayFor(modelItem => item.Office) </td> <td> @Html.DisplayFor(modelItem => item.Salary) </td> <td> <a class="btn btn-primary btn-sm" onclick="Edit('@Url.Action("AddOrEdit", "Employee", new { [email protected]})')"><i class="fa fa-pencil fa-lg"></i></a> <a class="btn btn-danger btn-sm" onclick="Delete('@Url.Action("Delete", "Employee", new { [email protected]})')"><i class="fa fa-trash fa-lg"></i></a> </td> </tr> } </tbody> </table> |
For this view, we have an IEnumerable of Employee as Model. No layout page used for this view. Employee records are listed using HTML table with id – employeeTable. Inside the last column we have added buttons for Edit and Delete Operation. Onclick events are added to both of them – Edit() and Delete(). When we click on Edit, we call HttpGet AddOrEdit action method with an employeeID, from that action method we will return a form to update the corresponding employee record. We show this form inside the second tab of tab control. Both these functions are discussed in later parts of this article.
We have added jQuery Datatable to add more functionalities to this HTML table. An example for jQuery Datatable can be found . In-order to activate this plugin for the table, we have defined a new function inside index view as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 | ... @section scripts{ ... <script> function activatejQueryTable() { $("#employeeTable").DataTable(); } $(function () { activatejQueryTable(); }); </script> } |
We call this activatejQueryTable() from document ready event.
Implement Insert and Update Operation
Now let’s return a form for Insert and Update Operation with HttpGet AddOrEdit.
1 2 3 4 5 6 7 8 9 10 11 12 13 | [HttpGet] public ActionResult AddOrEdit(int id = 0) { Employee emp = new Employee(); if (id != 0) { using (DBModel db = new DBModel()) { emp = db.Employees.Where(x => x.EmployeeID == id).FirstOrDefault<Employee>(); } } return View(emp); } |
For Insert Form( id will be 0), we will return a view with fresh Employee object. For Update form( id ≠ 0 ), method returns a view with an object for given EmployeeId.
Now let’s create a view for this AddOrEdit action method. You can use following Razor code in AddOrEdit.cshtml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | @model jQueryAjaxInAsp.NETMVC.Models.Employee @{ ViewBag.Title = "AddOrEdit"; Layout = null; } @using (Html.BeginForm("AddOrEdit", "Employee", FormMethod.Post, new { enctype = "multipart/form-data", onSubmit = "return jQueryAjaxPost(this);", data_restUrl = Url.Action("AddOrEdit", "Employee", new { id=0}) }))//data-reset { @Html.AntiForgeryToken() <div class="row"> <div class="form-horizontal"> @Html.ValidationSummary(true) @Html.HiddenFor(model => model.EmployeeID) @Html.HiddenFor(model => model.ImagePath) <div class="col-md-6"> <div class="form-group"> @Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Name) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Position, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Position, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Position) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Office, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Office, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Office) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Salary, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Salary, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Salary) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Submit" class="btn btn-default" /> @if (Model.EmployeeID != 0) { <a class="btn btn-success" onclick="refreshAddNewTab('@Url.Action("AddOrEdit","Employee",new{id=0})',false)"><i class="fa fa-plus"></i> Add New</a> }</div> </div> </div> <div class="col-md-6"> <div class="form-group"> @Html.LabelFor(model => model.ImagePath, new { @class = "control-label col-md-2" }) <div class="col-md-10"> <img src="@Url.Content(Model.ImagePath)" style="margin:10px" height="200" width="200" id="imagePreview"/> <input type="file" name="ImageUpload" accept="image/jpeg, image/png" onchange="ShowImagePreview(this,document.getElementById('imagePreview'))" /> </div> </div> </div> </div> </div> } |
Inside this view, we have a lot of things to discuss. Model for this view is Employee class from ADO.NET Entity Data Model. We don’t need a layout page for this, that’s why we set Layout as null.
We created the form with the using statement as follows
1 2 3 4 | @using (Html.BeginForm("AddOrEdit", "Employee", FormMethod.Post, new { enctype = "multipart/form-data", onSubmit = "return jQueryAjaxPost(this);", data_restUrl = Url.Action("AddOrEdit", "Employee", new { id=0}) })) ... } |
First two parameters of BeginForm() method tells where do we want to post the form after submission. Then we specified two attributes.
- Since this form contains file upload we set enctype to ‘multipart/form-data’.
- Then we’ve data attribute data-resetUrl, inside this we have an Url to reset this form controls to it’s initial state. Here we written underscore instead of hyphen ( data_restUrl instead of data-restUrl ), after rendering it will convert to hyphen format.
jQuery Ajax Operations With JSON
Finally we wired up a Submit event to jQueryAjaxPost() function. We’ll define this function inside our script file Scripts.js.
We have designed this form using Bootstrap as a series label-text pair. For text boxes we have applied bootstrap class form-control like this.
1 | @Html.EditorFor(...., new { htmlAttributes = new { @class = "form-control" } }) |
In-order to work this way, you must have MVC version greater than or equal to MVC 5.1. To update your existing project, Select the project from Solution Explorer. Go to Tools > Library package Manager > Package Manager Console. Then use following NuGet Command.
1 | Install-Package Microsoft.AspNet.Mvc -Version 5.1.1 |
Then we have an img controll with id ‘imagePreview’ to show preview of selected image for upload. Then we have a file up-loader as follows
1 2 | <input type="file" name="ImageUpload" accept="image/jpeg, image/png" onchange="ShowImagePreview(this,document.getElementById('imagePreview'))" /> |
name of this control must match with HttpFileBase property ImageUpload from model class Employee. accept attribute indicate allowed image extensions for upload. Finally we have wired up onchange event to ShowImagePreview() function. To display preview of selected image for upload.
Now we have to define these script functions for – ShowImagePreview() and jQueryAjaxPost() inside Scripts.js file as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | ... function ShowImagePreview(imageUploader, previewImage) { if (imageUploader.files && imageUploader.files[0]) { var reader = new FileReader(); reader.onload = function (e) { $(previewImage).attr('src', e.target.result); } reader.readAsDataURL(imageUploader.files[0]); } } function jQueryAjaxPost(form) { $.validator.unobtrusive.parse(form); if ($(form).valid()) { var ajaxConfig = { type: 'POST', url: form.action, data: new FormData(form), success: function (response) { if (response.success) { $("#firstTab").html(response.html); refreshAddNewTab($(form).attr('data-restUrl'), true); $.notify(response.message, "success"); if (typeof activatejQueryTable !== 'undefined' && $.isFunction(activatejQueryTable)) activatejQueryTable(); } else { $.notify(response.message, "error"); } } } if ($(form).attr('enctype') == "multipart/form-data") { ajaxConfig["contentType"] = false; ajaxConfig["processData"] = false; } $.ajax(ajaxConfig); } return false; } function refreshAddNewTab(resetUrl, showViewTab) { $.ajax({ type: 'GET', url: resetUrl, success: function (response) { $("#secondTab").html(response); $('ul.nav.nav-tabs a:eq(1)').html('Add New'); if (showViewTab) $('ul.nav.nav-tabs a:eq(0)').tab('show'); } }); } ... |
ShowImagePreview() function is straight forward, it has two parameter – file up-loader and image for preview. if there is an image for upload it will be shown inside preview img control.
refreshAddNewTab() – It will replace the form with fresh form returned from resetUrl. In this case, it will be an URL for HttpGet AddOrEdit action method. Inside the function we made a jQuery Ajax call to MVC action method. If showViewTab parameter is true, first ‘ViewAll’ tab will be activated.
jQueryAjaxPost() – This is the meat of this article – Asp.Net MVC With jQuery Ajax. Here we make the first jQuery ajax post request to mvc action method AddOrEdit.
First of all we manually called for client side validation with following line.
1 | $.validator.unobtrusive.parse(form); |
We made Name property as mandatory field for the form, If validation fails, validation error will shown.
If the form is valid, we will go for jQuery Ajax Post Operation. After Insert / Update Operation, HttpPost action method AddOrEdit will return a JSON data. returned JSON object contains success property to indicate whether server side operation is success or not, along with that it has message property to return notification message contains message or exception message in case of an error.
After Insert/ Update Operation, It will return HTML of ViewAll action method with updated employee list inside JSON property html. we replace this html inside first Bootstrap tab View All. Then replace the form with fresh AddOrEdit form with data-restUrl attribute of the form and we will make first tab as active. After that we have shown the notifyjs message popup. Then we called activatejQueryTable() function to convert HTML table to jQuery Datatable, before that we made check whether there is a function with this name or not. These script functions are written for general purpose, There might be other MVC controller which may not need this function call.In that case you can avoid the function activatejQueryTable() from Index view.
Following lines are special for forms with file upload.
1 2 3 4 | if ($(form).attr('enctype') == "multipart/form-data") { ajaxConfig["contentType"] = false; ajaxConfig["processData"] = false; } |
Server Side Operation – Insert and Update Operation
Above form will be submitted to HttpPost action method, where we need to implement Insert or Update operation as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | [HttpPost] public ActionResult AddOrEdit(Employee emp) { try { if (emp.ImageUpload != null) { string fileName = Path.GetFileNameWithoutExtension(emp.ImageUpload.FileName); string extension = Path.GetExtension(emp.ImageUpload.FileName); fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension; emp.ImagePath = "~/AppFiles/Images/" + fileName; emp.ImageUpload.SaveAs(Path.Combine(Server.MapPath("~/AppFiles/Images/"), fileName)); } using (DBModel db = new DBModel()) { if (emp.EmployeeID == 0) { db.Employees.Add(emp); db.SaveChanges(); } else { db.Entry(emp).State = EntityState.Modified; db.SaveChanges(); } } return Json(new { success = true, html = GlobalClass.RenderRazorViewToString(this, "ViewAll", GetAllEmployee()), message = "Submitted Successfully" }, JsonRequestBehavior.AllowGet); } catch (Exception ex) { return Json(new { success = false, message = ex.Message }, JsonRequestBehavior.AllowGet); } } |
First of all, If there is an image for upload. we will a custom file by appending formatted datetime to original filename in-order to avoid duplicate file name inside Images folder, then save the image inside Images folder. After that we will do Insert or Update Operation based on EmployeeID value.
Inside the form we kept an hidden field for EmployeeID and ImagePath. This ImagePath contains previous image path before update operation, if there is not image selected for upload (during update operation) we can use that.
Finally we returns a JSON data, for html property we called another function RenderRazorViewToString(), it will return HTML string of a view with given model. in-order to define the function I have added new C# class file – GlobaalClass, inside that we defined the function as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 | public static string RenderRazorViewToString(Controller controller, string viewName, object model = null) { controller.ViewData.Model = model; using (var sw = new StringWriter()) { ViewEngineResult viewResult; viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName); var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw); viewResult.View.Render(viewContext, sw); viewResult.ViewEngine.ReleaseView(controller.ControllerContext, viewResult.View); return sw.GetStringBuilder().ToString(); } } |
How to Update an Employee Record
In-order to update an employee you can click on edit button from ViewAll view last column. It will call JavaScript function Edit() as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 | ... function Edit(url) { $.ajax({ type: 'GET', url: url, success: function (response) { $("#secondTab").html(response); $('ul.nav.nav-tabs a:eq(1)').html('Edit'); $('ul.nav.nav-tabs a:eq(1)').tab('show'); } }); } .. |
It will populate the form for update operation inside the second tab. Upon form submission it will go to HttpPost action method and It will update the record as we discussed.
Delete an Employee Record
In-order Delete an Employee, you can click on delete button inside ViewAll view. It will call script function Delete() to HttpPost Delete action method. Here is the script function Delete().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ... function Delete(url) { if (confirm('Are you sure to delete this record ?') == true) { $.ajax({ type: 'POST', url: url, success: function (response) { if (response.success) { $("#firstTab").html(response.html); $.notify(response.message, "warn"); if (typeof activatejQueryTable !== 'undefined' && $.isFunction(activatejQueryTable)) activatejQueryTable(); } else { $.notify(response.message, "error"); } } }); } } ... |
Inside success function, we update the view all table with updated employee records. then shown NotifyJs notification and activated jQueryDataTable for updated Employee list.
Here is the HttpPost Delete action method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ... [HttpPost] public ActionResult Delete(int id) { try { using (DBModel db = new DBModel()) { Employee emp = db.Employees.Where(x => x.EmployeeID == id).FirstOrDefault<Employee>(); db.Employees.Remove(emp); db.SaveChanges(); } return Json(new { success = true, html = GlobalClass.RenderRazorViewToString(this, "ViewAll", GetAllEmployee()), message = "Deleted Successfully" }, JsonRequestBehavior.AllowGet); } catch (Exception ex) { return Json(new { success = false, message = ex.Message }, JsonRequestBehavior.AllowGet); } } ... |
Inside this Asp.Net MVC With jQuery Ajax Application, we implemented CRUD Operations – Insert Update and Delete.
Loading Spinner / Image in Asp.Net MVC
Finally I want to show the loading spinner div from _Layout page.
1 2 | <div class="loaderbody" id="loaderbody"> <div class="loader"></div></div> |
We already added loading to this using CSS style sheet Site.css. Using jQuery we will show and hide this div during jQuery Ajax Operations. for that we following code inside Scripts.js with document ready event.
1 2 3 4 5 6 7 8 | $(function () { $("#loaderbody").addClass('hide'); $(document).bind('ajaxStart', function () { $("#loaderbody").removeClass('hide'); }).bind('ajaxStop', function () { $("#loaderbody").addClass('hide'); }); }); |
Step by Step Video Tutorial
That’s all, let me know your comments and feedback. Happy Coding 🙂
Leave a Reply
8 Comments on "Asp.Net MVC With jQuery Ajax CRUD Operations Using JSON and EF"
This is what i was looking for. it just awesome. can your please do it same think without entity framework.
I’m glad you found the article helpful. In-order to replace EF with ADO method using SqlClient Or Dapper ORM. Please refernce following video tutorials
Using SqlClient Method :
Using Dapper ORM :
can you please create CURD Operation with asp.net gridview using bootstrap modal popup.
Great thanks
Very helpfull sir very concise.more power!
solid no words. everyone required this. nice, good, awesome………