jQuery Ajax CRUD in ASP.NET Core MVC with Modal Popup - CodAffection
[the_ad_placement id="before-content"]

jQuery Ajax CRUD in ASP.NET Core MVC with Modal Popup

How to Use jQuery Ajax in Asp.Net Core MVC for CRUD Operations with Modal Popup

In this article, we’ll discuss how to use jQuery Ajax for ASP.NET Core MVC CRUD Operations using Bootstrap Modal. When you implement CRUD operations without jQuery Ajax, for each user request the entire webpage is reloaded once again. With jQuery Ajax, we can make an HTTP request to controller action methods without reloading the entire page. This allows us to only re-render a portion of the application, which gives more performance and smaller bandwidth usage, similar to a single page application created with front-end frameworks like Angular or React.

To demonstrate CRUD operations – insert, update, delete and retrieve, the project will be dealing with details of a normal bank transaction. GitHub repository for this demo project : https://bit.ly/33KTJAu.

Sub-topics discussed :

  • Form design for insert and update operation.
  • Display forms in modal popup dialog.
  • Form post using jQuery Ajax.
  • Implement MVC CRUD operations with jQuery Ajax.
  • Loading spinner in .NET Core MVC.
  • Prevent direct access to MVC action method.

Create ASP.NET Core MVC Project

In Visual Studio 2019, Go to File > New > Project (Ctrl + Shift + N).
From new project window, Select Asp.Net Core Web Application.

Image showing how to create ASP.NET Core Web API project in Visual Studio.

Once you provide the project name and location. Select Web Application(Model-View-Controller) and uncheck HTTPS Configuration. Above steps will create a brand new ASP.NET Core MVC project.

Showing project template selection for .NET Core MVC.

Setup a Database

Let’s create a database for this application using Entity Framework Core. For that we’ve to install corresponding NuGet Packages. Right click on project from solution explorer, select Manage NuGet Packages, From browse tab, install following 3 packages.

Showing list of NuGet Packages for Entity Framework Core

Now let’s define DB model class file – /Models/TransactionModel.cs.

Here we’ve defined model properties for the transaction with proper validation. Now let’s define DbContext class for EF Core.

This class decide what should be there in actual physical db after db migration. To create a table – Transactions for the above model, we have added a corresponding DbSet property – Transactions. With ASP.NET Core dependency injection we’ll be creating new instance of   DbContext class, That we can do in Startup.cs file as shown below.

While creating the class instance, value of it’s constructor parameter is necessary. The context class constructor parameter DbContextOptions, need information like database provider(SQL Server, MySQL, Oracle, etc.) and it’s connection string. Now let’s add the connection string – DevConnection, in appsettings.json.

To create the actual physical database as per the connection string, let’s execute following migration command one by one.

Add-Migration "InitialCreate"

After migration is completed, you could check whether the new database created as per our DB model or not.

Create MVC Controller with CRUD Action Methods

Now let’s add an MVC controller with action methods for CRUD operations. For that right-click on Controllers folder, Add > Controller. Then select ‘MVC Controller with views, using Entity Framework’. Fill up the window with corresponding details.

showing how to create an ASP.NET Core controller with actions and views using EF Core

If you face the following error while creating the controller. you should try again after installing the NuGet Package – Microsoft.VisualStudio.Web.CodeGeneration.Utils.

Error commonly shown while creating scaffolded controller in visual studio.

Inside the controller, you could see action methods for the crud operations for both GET and POST request. As you know the instance of this controller is automatically created by ASP.NET Core framework when a request is made into it. At the same time the value for it’s constructor parameter TransactionDbContext is passed from the dependency injection.

Let’s Start Designing the App

First of all, we want to add style-sheet reference for Google Font Roboto and Font Awesome Icon in main layout – _Layout.cshtml.

Now let me update the global stylesheet (wwwroot/css/site.css) with all the required css rules for entire application.

 font-family: 'Roboto', sans-serif; 

/* Change input control border color */
.form-control, .input-group-text {
    border: 1px solid #0080ff;

    cursor: pointer !important;

.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: 80px;
    height: 80px;
    animation: spin 2s linear infinite;
    position: fixed;
    top: 45%;
    left: 40%;

@keyframes spin {
    0% {
        transform: rotate(0deg);

    100% {
        transform: rotate(360deg);


You could access the newly created controller action methods with an URL of the format – /Transaction/[action_name]. You can configure this controller as default route in Startup.cs.

Inside the controller index action, we retrieve all of the records from transactions table. Let’s update the corresponding index view from which we’ve to do all other operations with the help of jQuery Ajax.

Inside this index view, we’ve done some major changes. First of all added the validation scripts in Scripts section. By default in index.html, we had a table for listing transaction records. we’ve to move that into a new partial view _ViewAll. We’ve to re-render the table after each operation like insert, update and delete. So it’s better to move the table into a separate partial view for jQuery Ajax Get request later. Create the file _ViewAll.cshtml in /Views/Transaction folder as shown below.

Inside this partial view, we have a button for insert operation in table header. Each record has buttons for update and delete. All of these button’s click event is bound to their JavaScript functions. we can discuss that later. Now you could see the empty table, if you navigate the index action – /Transaction/Index.

Implement Insert and Update Operation

In transaction controller, you could see Add and Edit action methods with their razor views. In this project, we will combine these two action methods and their views into one – AddOrEdit. For AddOrEdit view, you just need to make few changes in existing view Edit.cshtml. First of all, rename the file to AddOrEdit.cshtml and update the file as shown below.

There are some re-arrangement for input controls, other than that, we’ve changed the form post action method to AddOrEdit and asp-route-id is set to PK property – TransactionId. In this view, you could see an additional hidden property – Date. Which is the data of transaction.

Now let’s define the corresponding GET and POST action method AddOrEdit in TransactionController.

Inside these action methods, we just combined existing Create and Edit action methods. To know whether we’ve an insert or update operation, we can check id(TransactionId) parameter. if its value is zero then we’ve an insert operation otherwise its an update operation.

From GET action method, if id is zero a fresh transaction form will be returned else corresponding transaction details will populated in returned form. Inside POST action method, Insert/ Update operation will be done based on the id. The request into this POST action method will be made using jQuery Ajax. so the action method must return a JSON objectWith that object list of transactions can be replaced, _ViewAll action method is passed in html property. In order to convert a view into HTML string, we’ve defined a function inside a new C# file – Helper.cs as shown below.

How to do jQuery Ajax Form Post in ASP.NET MVC

Related to AddOrEdit action method, we bound two JavaScript functions.

  • showInPopup() which open response from a GET request in Bootstrap modal popup.
  • jQueryAjaxPost() submit a form using jQuery Ajax.

Now let’s define these functions in wwwroot/js/site.js.

To open a request-response with showInPopup function, we’ve used bootstrap modal, so let’s add its HTML elements in _Layout.cshtml as shown below, just before the footer.

Inside showInPopup method, we will make the GET request to the given URL, and request-response is saved inside modal-bodydiv. we opened the Bootstrap model with the modal function. This showInPopup function is called for adding new transactions from table header button and also from edit/ update button to show particular transaction details for update operation.

In jQueryAjaxPost function, we’ve to do following operations

  • Form Validation : before submitting the form, we’ve to validate the form controls. If validation is failed, the same form will be shown with validation error messages/ indications.
  • Form Submission : successful validation guarantee integrity of data. Now we can make the jQuery Ajax post request to form action URL. If the request is successful, returned html response string for the table is replaced in place of current table div. finally to prevent the form from default form submission, we have returned false.

Both insert and update operation is made from this function. After all, the modal popup will look like this.

modal popup is opened with a form

Delete a Record with jQuery Ajax

Now let’s delete a record with the help of jQuery Ajax, we’ve already added the delete button for each table row. Actually it is a form with a submit button. Its always recommended to implement delete operation with a post request. Here we called DeleteConfirmedaction method (URL – Transaction/Delete). Now we’ve to update the corresponding delete post action method as shown below.

Now let’s add corresponding jQuery Ajax post method- jQueryAjaxDelete in wwwroot/js/site.js.

After the delete operation, HTML string from _ViewAll is replaced in place of the table. That’s it, we’ve completed with implementing jQuery Ajax CRUD operations in ASP.NET Core MVC. As of now our application will look like this.

screen shot of the app with jquery ajax crud in asp.net crud

Add Loading Spinner

When there is ongoing operation involve with server, there will be some delay. Instead of showing an idle interface, displaying loading spinner is recommended because of 2 reason.

  1. user knows an ongoing request is happening in back-end. Need to wait few more seconds until it completes its execution.
  2. prevents the user from making further interaction with interface. hence prevent the browser from hanging.

Now let’s look how to add loading spinner in ASP.NET MVC during jQuery Ajax request, First of all, add following div in main layout _Layout.cshtml, just above the footer.

We’ve already added it’s corresponding CSS styles with animation in site.css. Using jQuery we’ve to show and hide this spinner during Ajax request-response with the help of jQuery load event in wwwroot/js/site.js.

Prevent Direct Access to Action Methods

In this application, we accessed the AddOrEdit action method through jQuery Ajax GET request. you can also access the same GET action method with an URL – /Transaction/AddOrEdit. But it will only contain the form without a layout, so it won’t work as we expect. If there is any such action methods only defined for jQuery Ajax request, we’ve to block the direct access to them. For that, we can create a NoDirectAccess attribute in Helper.cs file.

Now you just need to add this attribute to GET action method AddOrEdit as shown below.

That’s all for now, Following discussions will help you to add rest of the features.

Video Tutorial

In our YouTube channel, we have discussed the same topic in following video.

36 thoughts on “jQuery Ajax CRUD in ASP.NET Core MVC with Modal Popup”

  1. After the Edit any data & go to Creating a new data, at that time model body show last Edited data how can I solve this please help me.

    After the refresh the page, Creating new data work completely.

  2. hi.
    I need to have pagination and sort and search capability for this.
    project would you please add these features?

    thanks a lot

  3. Why the logic of adding and editing was combined into one method and one view. Is it the so problem to write different actions and views.
    Each method should be responsible for one thing

    1. I agree with Single Responsibility of functions/ views/ actions. Since this is a demonstration I’ve gone for the easy approach.
      Even though, unlike functions, for views, if there is no considerable difference in design logic. I usually combine them into one like AddOrEdit.
      If there is a need for design change, we only need to make it in one place. if they are separate like Add and Edit. we need to do that on both files.
      It will become more annoying especially in a large application.
      Eg. Change Submit Button text from ‘Submit’ to ‘Save’ and ‘Update’. It must be done through out the views with forms.

      If you really want to apply single responsibility principle in views you should consider using partial view.

  4. Hello there

    I have to carry my project on usb memory. Sometimes I open the project at home and sometimes at school. I want to create the database in the “App_Data” folder in the project. Can you edit the files for me? “appsettings.json” “Startup.cs”

    I tried a lot but couldn’t succeed.

    Sample Code:

    Thanks in advance

  5. showPopupPost = (url, title) => {
    type: “get”,
    url: url,
    success=function (res) {
    $(“#form-modal .modal-body”).html(res);
    $(“#form-modal .modal-title”).html(title);



    This code is not working I am getting uncaught refrence error at HTML anchor element onclick

  6. showInPopup = (url, title) => {
    type: ‘GET’,
    url: url,
    success: function (res) {
    $(‘#form-modal .modal-body’).html(res);
    $(‘#form-modal .modal-title’).html(title);

    this block does not execute after I debug. so dialog not display. I don’t why on this to solve it. Please give me some advise.

  7. Very nice tutorial… Congrat for it.

    Just one question, I tried to add Dropdown list with SelectList in ViewModel, but it wont work, show empty Form.

    probable the Ajax Code requere a different aproach. Could you point me to the right direction.

  8. I need some help in this program . when i add-Migration show some problem value cannot be null. Parameter connectionString. You can help me to solve this problem.

  9. Hi. Same problem. there is no problem when I use just string url. But when if I use Url.Action like there occurs a problem.
    After the any update proccess save button’s url contain last route values.
    I think problem is about RenderRazorViewToString helper.

  10. Hi Shamseer,
    Thanks for this wonderful tutorial.

    I have notices that when I used Select2,datepicker range and bootstrap switch for checkbox , they are not working when view is embedded in modal bootstrap. All the efforts I have made are in vain. Any support on what I can do to sort this out will be highly appreciated.

    Best Regards,

  11. Hi. It’s good tutorial apart from I’m stuck on error in VS 2019, when adding Controller of TransactionController.

    Error – There was an error running the selected code generator:’‘Package restore failed.Rolling back package changes for ‘jQueryAjaxCRUDInAspNetCore’

    Any help will be useful, thanks

  12. Tufan Karakaya

    Hi article and good explanation.

    How to implement Ajax Crud with modal popup on master details entities for details.
    For examples, SalesOrder, SalesOrderLine. I want to CRUD SalesOrderLine Ajax Modal Popup style with SalesOrder.
    Can you make an example for that scenario?

  13. When i click update and save new informations, then reclick for Add popup (should be empty), I found weirdly filled with the last element updated…
    when I checked the html code i find the URL.Action of new(Add) contain in route values the id of last updated…
    How this is possible? and how i can fix it

    1. Hi. Same problem. there is no problem when I use just string url. But when if I use Url.Action like there occurs a problem.
      After the any update proccess save button’s url contain last route values.
      I think problem is about RenderRazorViewToString helper.

    2. Hi. Same problem. there is no problem when I use just string url. But when if I use Url.Action there occurs a problem.
      After the any update proccess new transaction button’s url contain last route values.
      why ? I think problem is about RenderRazorViewToString helper.

    3. I noticed that if I use the url action just like below, there no occurs problem. I used id=0 instead of null.
      @Url.Action(“AddOrEdit”,”Product”, new {id=0}, Context.Request.Scheme)

  14. How to implement client side (unobtrusive) validation or best fluent validaiton ? I tried but i couldn’t run, please help me ?

  15. If you can setup your table like website datatables.net, you will have the best tutorial .Net Core MVC with popup.

  16. Dear Sir/Mam,

    I am getting error like as below mentioned when I add Transactioncontroller
    there was an error running the selected code generator: ‘package restore failed.Rolling back package changes for ‘jQueryAjaxCRUDInAspNetCore’

    1. Hi Akshay…I was facing same error but i have resolved it..

      I was able to resolve this issue using “Manage NUGET Packages for Solution”, then performing an “Update All”.
      This set my AspNetCore version to 3.1.4 for all packages and resolved my “Package Restore Failed” error.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top
Share via
Copy link
Powered by Social Snap