100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
.NET Framework

AJAX in MVC

How to use AJAX with jQuery and JsonResult actions to build partial-page updates and asynchronous interactions in ASP.NET MVC.

Models and DataIntermediate8 min readJul 10, 2026
Analogies

Why Use AJAX in an MVC Application?

AJAX (Asynchronous JavaScript and XML, though modern usage almost always means JSON) lets a browser send a request to an MVC action and update part of the page with the response without a full page reload. In practice this means a controller action returns JsonResult via return Json(data) for a JavaScript-driven UI update, or PartialViewResult via return PartialView("_ProductRow", model) when you want the server to render a chunk of HTML that jQuery's $.ajax success callback then injects into the DOM with $("#container").html(response), avoiding the cost and jarring UX of reloading the entire page for a small interaction like adding an item to a cart.

🏏

Cricket analogy: It is like a stadium's electronic scoreboard updating just the 'runs' digit the instant a boundary is hit, instead of the entire scoreboard going dark and rebooting; fans watching a run-chase like Rohit Sharma's chase-master innings never lose sight of the overall picture during the update.

Returning JSON and Partial Views

A controller action intended purely for data exchange typically returns JsonResult, and when the request originates from a script rather than a browser address bar, GET requests returning JSON must explicitly pass JsonRequestBehavior.AllowGet — return Json(data, JsonRequestBehavior.AllowGet) — because MVC blocks JSON GET responses by default as a defense against a JSON hijacking vulnerability. When the AJAX call needs to update a chunk of markup rather than raw data, returning PartialView("_ProductRow", product) renders just that Razor partial's HTML server-side and sends it back, letting the client simply swap it into the DOM instead of the client reconstructing HTML from JSON in JavaScript.

🏏

Cricket analogy: It is like a broadcaster deciding whether to send viewers raw ball-tracking data for their own fantasy app, or a fully rendered highlight clip ready to play — sometimes you want structured numbers, other times pre-rendered content, similar to how Hawk-Eye data feeds differ from broadcast replay packages.

csharp
// Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddToCart(int productId, int quantity)
{
    var product = db.Products.Find(productId);
    if (product == null)
        return Json(new { success = false, message = "Product not found" });

    cartService.Add(productId, quantity);
    return Json(new { success = true, cartCount = cartService.GetItemCount() });
}

public ActionResult ProductRow(int id)
{
    var product = db.Products.Find(id);
    return PartialView("_ProductRow", product); // renders _ProductRow.cshtml
}
javascript
$('#add-to-cart-btn').on('click', function () {
    var productId = $(this).data('product-id');

    $.ajax({
        url: '/Cart/AddToCart',
        type: 'POST',
        data: {
            productId: productId,
            quantity: 1,
            __RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val()
        },
        success: function (response) {
            if (response.success) {
                $('#cart-count').text(response.cartCount);
            } else {
                alert(response.message);
            }
        },
        error: function () {
            alert('Something went wrong. Please try again.');
        }
    });
});

CSRF Protection and Error Handling in AJAX Calls

POST actions decorated with [ValidateAntiForgeryToken] still require the anti-forgery token even when called via AJAX, so the token generated by @Html.AntiForgeryToken() in the view must be read from the DOM and included explicitly in the $.ajax data payload, as shown above — omitting it causes every AJAX POST to fail with a 400 error. On the client, every $.ajax call should define both success and error callbacks, because network failures, server exceptions, and validation failures all surface differently: a 500 error lands in the error callback, while a deliberately returned Json(new { success = false, errors = ModelState... }) lands in success but still needs application-level handling to show the user what went wrong.

🏏

Cricket analogy: It is like an umpire refusing to allow a bowler to bowl the next over without physically checking the ball hasn't been tampered with, no matter how routine the over looks; skipping that verification step, even in a friendly match, invalidates the delivery, similar to how ball-checks are mandatory even in a low-stakes fixture.

For AJAX forms rendered with Ajax.BeginForm() (from the Microsoft AJAX helpers, requiring jquery.unobtrusive-ajax.js), the anti-forgery token is included automatically as a hidden field inside the form and submitted along with the rest of the form data, so no manual token handling is needed the way it is with a raw $.ajax call.

Never skip the error callback in a $.ajax call. Silent failures — where a 500 error or network timeout leaves the UI looking like nothing happened — are one of the most common usability complaints in AJAX-heavy MVC applications, and users are left clicking a button repeatedly with no feedback.

  • AJAX lets an MVC action update part of a page without a full reload, using JsonResult for data or PartialViewResult for server-rendered HTML fragments.
  • GET actions returning JSON must pass JsonRequestBehavior.AllowGet to bypass MVC's default JSON hijacking protection.
  • PartialView("_Name", model) renders a Razor partial server-side, which the client injects directly into the DOM.
  • [ValidateAntiForgeryToken] still applies to AJAX POSTs — the token must be read from the DOM and sent explicitly.
  • Every $.ajax call should define both success and error callbacks to handle network failures and server exceptions distinctly.
  • Application-level failures (like validation errors) are often returned as a 200 response with a success:false payload, requiring explicit handling even inside the success callback.
  • Ajax.BeginForm() with jquery.unobtrusive-ajax.js automatically includes the anti-forgery token, unlike raw $.ajax calls.

Practice what you learned

Was this page helpful?

Topics covered

#NETFramework#ASPNETMVCStudyNotes#MicrosoftTechnologies#AJAXInMVC#AJAX#MVC#Application#Returning#StudyNotes#SkillVeris