Complete Guide to Sending and Receiving JSON Data via AJAX in ASP.NET MVC

Oct 28, 2025 · Programming · 16 views · 7.8

Keywords: ASP.NET MVC | AJAX | JSON Data Exchange | Model Binding | C# Controller

Abstract: This article provides a comprehensive exploration of the complete workflow for correctly sending JSON data to controllers and receiving JSON responses in the ASP.NET MVC framework. Covering data serialization on the JavaScript side, AJAX request configuration, model binding in C# controllers, and JSON response handling, it offers thorough technical analysis and best practices. By refactoring the original problematic code, it demonstrates key steps including using JSON.stringify() for data serialization, setting contentType to application/json, and properly configuring model binding in controllers. The article also analyzes common issues such as null parameters and their solutions, providing complete code examples and in-depth technical insights.

Introduction

In modern web development, asynchronous data exchange via AJAX has become a standard practice. JSON, as a lightweight data interchange format, plays a crucial role in client-server communication. However, properly handling the sending and receiving of JSON data in the ASP.NET MVC framework often presents numerous challenges, particularly when controller parameters unexpectedly become null.

Problem Analysis

In the original code, when JavaScript sends data to an ASP.NET MVC controller via AJAX, the sendInfo parameter in the controller method consistently remains null. The root cause of this issue lies in improper configuration of data serialization and model binding. Specifically, JavaScript objects are not correctly serialized to JSON before sending, and the AJAX request's contentType setting does not match, preventing the server from properly parsing the data in the request body.

JavaScript Implementation

Correct JavaScript implementation requires attention to two key aspects: data serialization and AJAX configuration. First, use the JSON.stringify() method to convert JavaScript objects to JSON strings, ensuring the data format meets server expectations. Second, explicitly specify contentType as application/json; charset=utf-8 in the AJAX configuration to inform the server of the request body's data format.

function addNewManufacturer() {
    var name = $("#id-manuf-name").val();
    var address = $("#id-manuf-address").val();
    var phone = $("#id-manuf-phone").val();
    
    var person = {
        Name: name,
        Address: address,
        Phone: phone
    };
    
    $.ajax({
        type: "POST",
        url: "/Home/Add",
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify(person),
        success: function(response) {
            if (response.msg) {
                alert("Manufacturer " + name + " was successfully added to the list!");
                location.reload(true);
            } else {
                alert("Cannot add to list!");
            }
        },
        error: function(xhr, status, error) {
            alert("Request failed: " + error);
        }
    });
}

In this implementation, JSON.stringify(person) serializes the JavaScript object to a JSON string, while contentType: "application/json; charset=utf-8" ensures the server correctly identifies the request format. The success callback function processes the JSON response from the server, accessing response data through response.msg.

C# Model Definition

Server-side model definitions must align with client data structures and use property accessors to ensure the model binder can correctly populate data. The original code's use of a struct without property accessors was a significant factor in binding failure.

public class Person
{
    public string Name { get; set; }
    public string Address { get; set; }
    public string Phone { get; set; }
}

public class PersonModel
{
    private List<Person> _list;
    
    public PersonModel() 
    {
        _list = new List<Person>();
    }
    
    public bool AddNewPerson(Person info)
    {
        if (info == null)
        {
            throw new ArgumentException("Person information cannot be null", nameof(info));
        }
        
        // In real applications, this might include data validation logic
        _list.Add(info);
        
        return true;
    }
    
    public List<Person> GetAllPersons()
    {
        return _list;
    }
}

This model definition uses a class instead of a struct and provides { get; set; } accessors for all properties, which is essential for the ASP.NET MVC model binder to function correctly. The model class also includes basic data validation and business logic.

Controller Implementation

As the entry point for client requests, the controller must properly handle JSON data binding and business logic invocation. In ASP.NET MVC, the model binder automatically maps request data to method parameters, but requires correct configuration.

[HttpPost]
public ActionResult Add(Person person)
{
    try
    {
        if (person == null)
        {
            return Json(new { msg = false, error = "Received data is null" });
        }
        
        // Data validation
        if (string.IsNullOrWhiteSpace(person.Name))
        {
            return Json(new { msg = false, error = "Name cannot be empty" });
        }
        
        PersonModel model = new PersonModel();
        bool success = model.AddNewPerson(person);
        
        return Json(new { 
            msg = success, 
            message = "Successfully added " + person.Name 
        });
    }
    catch (Exception ex)
    {
        return Json(new { 
            msg = false, 
            error = "Error during processing: " + ex.Message 
        });
    }
}

The controller method receives a parameter of type Person, and the model binder automatically maps JSON data to this object. The method includes basic data validation and exception handling to ensure system robustness. Responses are returned via the Json() method, maintaining data format consistency with the client.

In-Depth Technical Analysis

The model binding process involves multiple key components working together. When an AJAX request reaches the server, ASP.NET MVC's model binding system selects the appropriate value provider based on the request's contentType. For application/json content types, the system uses a JSON value provider to parse the request body.

In ASP.NET Core, this process has changed, requiring explicit use of the [FromBody] attribute to specify the parameter binding source:

[HttpPost]
public ActionResult Add([FromBody] Person person)
{
    // Processing logic
}

This change is primarily for security considerations, particularly cross-site request forgery (CSRF) protection. By explicitly specifying the binding source, potential security vulnerabilities can be avoided.

Error Handling and Debugging

In practical development, proper error handling and effective debugging are crucial. Common debugging techniques include:

[HttpPost]
public ActionResult Add(Person person)
{
    if (!ModelState.IsValid)
    {
        var errors = ModelState.Values
            .SelectMany(v => v.Errors)
            .Select(e => e.ErrorMessage);
        return Json(new { 
            msg = false, 
            errors = errors.ToArray() 
        });
    }
    
    // Normal processing logic
}

Performance Optimization Considerations

In large-scale applications, performance optimization for JSON data exchange deserves attention:

Security Best Practices

When handling JSON data, security considerations cannot be overlooked:

Conclusion

By systematically addressing AJAX JSON data exchange in ASP.NET MVC, robust and efficient web applications can be built. Key success factors include: correct data serialization, appropriate contentType configuration, complete model definitions, and sound error handling mechanisms. The complete solution and in-depth analysis provided in this article offer reliable technical reference for developers implementing similar functionality in practical projects.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.