Tutorials ASP.NET Core MVC Mastery

JsonResult

On this page

JsonResult in ASP.NET Core MVC β€” Returning Data for AJAX & APIs

Not every controller action needs to return a full HTML page. When your front-end JavaScript makes AJAX calls, or when you're building lightweight API endpoints within an MVC project, you need to return structured JSON data. JsonResult is your tool for exactly this β€” clean, serialized JSON responses from within MVC controllers.

1. WHAT is JsonResult?

JsonResult is an ActionResult type that serializes an object to JSON format and sends it as the HTTP response body with the content type application/json. It's part of the Microsoft.AspNetCore.Mvc namespace and is returned using the Json() helper method.

ActionResult Family Tree
ActionResult
β”œβ”€β”€ ViewResult          β†’ Returns HTML page
β”œβ”€β”€ JsonResult          β†’ Returns JSON data    ← You are here
β”œβ”€β”€ PartialViewResult   β†’ Returns HTML fragment
β”œβ”€β”€ RedirectResult      β†’ Redirects to URL
β”œβ”€β”€ ContentResult       β†’ Returns raw string
β”œβ”€β”€ FileResult          β†’ Returns file download
└── StatusCodeResult    β†’ Returns HTTP status code

2. WHY Use JsonResult?

  • AJAX Responses: When JavaScript on your page calls the server (using fetch() or jQuery.ajax()), it expects JSON, not HTML
  • Hybrid MVC/API: You're building an MVC app but need a few endpoints that return data for charts, dropdowns, or live search
  • SPA Communication: Your Razor views load initially, then React/Vue components make API calls for dynamic data
  • Performance: Sending a small JSON payload is far faster than rendering a full Razor view

3. REAL-TIME PRODUCTION EXAMPLES

Example 1: Basic Usage β€” Returning Product Data

public class ProductsController : Controller
{
    private readonly IProductService _productService;

    public ProductsController(IProductService productService)
        => _productService = productService;

    // Returns JSON for AJAX calls
    public async Task<IActionResult> GetProductJson(int id)
    {
        var product = await _productService.GetByIdAsync(id);
        if (product == null)
            return NotFound(new { success = false, message = "Product not found" });

        // The Json() method serializes the object and sets Content-Type: application/json
        return Json(new
        {
            success = true,
            data = new
            {
                product.Id,
                product.Name,
                product.Price,
                product.Category,
                product.InStock
            }
        });
    }
}

Example 2: AJAX Live Search with JsonResult

// Controller β€” Search endpoint returning JSON
[HttpGet]
public async Task<IActionResult> Search(string query)
{
    if (string.IsNullOrWhiteSpace(query) || query.Length < 2)
        return Json(new { results = Array.Empty<object>() });

    var products = await _productService.SearchAsync(query, limit: 10);

    return Json(new
    {
        results = products.Select(p => new
        {
            p.Id,
            p.Name,
            p.Price,
            imageUrl = p.ImageUrl ?? "/img/placeholder.png",
            url = Url.Action("Details", "Products", new { id = p.Id })
        }),
        totalFound = products.Count
    });
}
// Front-end β€” JavaScript calling the endpoint
const searchInput = document.getElementById('searchBox');
searchInput.addEventListener('input', async function() {
    if (this.value.length < 2) return;

    const response = await fetch('/Products/Search?query=' + encodeURIComponent(this.value));
    const data = await response.json();

    // data.results is the JSON array from our controller
    const html = data.results.map(item =>
        '<a href="' + item.url + '" class="search-result">' +
        '<img src="' + item.imageUrl + '" /> ' + item.name +
        ' β€” $' + item.price + '</a>'
    ).join('');

    document.getElementById('searchResults').innerHTML = html;
});

Example 3: Custom JSON Serialization Options

// When you need camelCase, custom date formats, or null handling
public IActionResult GetOrderDetails(int id)
{
    var order = _orderService.GetById(id);

    // Custom serialization options per-response
    var options = new JsonSerializerOptions
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
        WriteIndented = false  // Compact in production
    };

    return new JsonResult(order, options);
}

// Global configuration in Program.cs (applies to ALL JSON responses)
builder.Services.AddControllersWithViews()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
        options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
        options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
    });

4. JsonResult vs Ok() vs ContentResult

MethodReturnsContent-TypeBest For
Json()JSON objectapplication/jsonMVC controllers returning data for AJAX
Ok()200 + optional bodyapplication/jsonAPI controllers (ControllerBase)
Content()Raw stringtext/plainReturning plain text, XML, or custom formats

5. Best Practices

βœ… DO
  • Always wrap responses in a consistent envelope: { success, data, message }
  • Configure global JSON options in Program.cs for consistency
  • Use camelCase naming to match JavaScript conventions
  • Return appropriate HTTP status codes alongside JSON
  • Use DTOs β€” never expose database entities directly in JSON
❌ DON'T
  • Don't return EF Core entities directly β€” circular references cause serialization errors
  • Don't ignore null handling β€” use WhenWritingNull to keep payloads clean
  • Don't forget CSRF token for POST requests from AJAX (use [ValidateAntiForgeryToken])
  • Don't mix MVC and API patterns β€” if you need full APIs, use ApiController

6. Interview Mastery

Q: "When would you use JsonResult in an MVC controller instead of creating a separate Web API controller?"

Architect Answer: "I use JsonResult when the AJAX endpoint is tightly coupled to a specific Razor view β€” like a live search box, a cascade dropdown, or a 'like' button. These are UI-driven interactions, not domain APIs. If the endpoint serves multiple consumers (mobile app, third-party integration, separate SPA), I create a proper [ApiController] with versioning, content negotiation, and proper REST semantics. The distinction is: JsonResult is for view support, ApiController is for domain services."

ASP.NET Core MVC Mastery
Course syllabus
1. Core Framework Introduction to ASP.NET Core MVC
MODULE 1: INTRODUCTION & ENVIRONMENT SETUP Microsoft Web Stack Overview Evolution of ASP.NET Environment Setup
2. View Engine Layouts & Partial Views in Razor
MODULE 2: .NET CORE FUNDAMENTALS Core Concepts Project Structure Startup Flow Middleware Pipeline
MODULE 3: ASP.NET CORE BASICS Creating Project CLI Commands wwwroot & Static Files
MODULE 4: MVC FUNDAMENTALS MVC Architecture Dependency Injection (DI) Service Lifetimes
MODULE 5: DATA PASSING TECHNIQUES ViewData vs ViewBag TempData ViewModel Pattern
MODULE 6: ROUTING Conventional vs Attribute Routing Custom Constraints
MODULE 7: VIEWS & UI Razor View Engine Layouts & Sections View Components
MODULE 8: ACTION RESULTS ViewResult JsonResult RedirectResult
MODULE 9: HTML HELPERS Form Helpers Custom HTML Helpers
MODULE 10: TAG HELPERS Built-in Tag Helpers Custom Tag Helpers
MODULE 11: MODEL BINDING FromQuery vs FromRoute Complex Binding
MODULE 12: VALIDATION Data Annotations Remote Validation Fluent Validation
MODULE 13: STATE MANAGEMENT Cookies & Sessions TempData
MODULE 14: FILTERS & SECURITY Action Filters Authorize Filters Anti-forgery
MODULE 15: ENTITY FRAMEWORK CORE (DEEP DIVE) DbContext Migrations LINQ Relationships
MODULE 16: DESIGN PATTERNS Repository Pattern Unit of Work Clean Architecture
MODULE 17: FILE HANDLING File Upload/Download PDF/Excel Generation
MODULE 18: ADVANCED ASP.NET CORE Request Lifecycle Bundling & Minification Deployment
MODULE 19: PERFORMANCE & BEST PRACTICES Caching Strategies Async Programming Secure Coding
MODULE 20: RAZOR PAGES (BONUS) Razor Pages vs MVC
MODULE 21: REAL-WORLD PROJECTS (πŸ”₯ MUST DO) E-Commerce Web Application Employee Management System
Toolliyo Assistant
Ask about tutorials, ebooks, training, pricing, mentor services, and support. I use public site content onlyβ€”not admin or internal tools.

care@toolliyo.com

Need callback? Share your details