Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQuery Ajax and ASP.NET MVC3 causing null parameters

This question has been asked many times but none of the solutions I found seem to be working. Makes me think this could be a new issue, and maybe something specific to ASP.NET MVC 3.

I am using JQuery Ajax to make a simple call to an ASP.NET MVC 3 controller. Like so

var addressInfo = { 
    Address1: "423 Judy Road",
    Address2: "1001",
    City: "New York",
    State: "NY",
    ZipCode: "10301",
    Country: "USA" 
};

$.ajax({
    url: '/home/check',
    type: 'POST',
    data: JSON.stringify(addressInfo),
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    success: function () {
        alert("success");
    },
    error: function () {
        alert("error");
    }
});

The controller looks like this

[HttpPost]
public ActionResult Check(AddressInfo addressInfo)
{
    // Do something and return Json(something)
}

This does not work, though it should have based on the "JavaScript and AJAX Improvements" section of Scottgu's post

I have tried many different variations of this, for example:

var args = new Object();
args.addressInfo = { 
    Address1: "423 Judy Road",
    Address2: "1001",
    City: "New York",
    State: "NY",
    ZipCode: "10301",
    Country: "USA" 
};

$.ajax({
    url: '/home/check',
    type: 'POST',
    data: JSON.stringify(args),
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    success: function () {
        alert("success");
    },
    error: function () {
        alert("error");
    }
});

And then both of the above directly with the JSON object:

$.ajax({
    url: '/home/check',
    type: 'POST',
    data: args,
    success: function () {
        alert("success");
    },
    error: function () {
        alert("error");
    }
});

None work. If I only have a string that I pass to the controller, that works. But as soon as I introduce an object, I cannot get it to work.

Anyone know what might be the issue.

Thanks a lot for looking into this!

like image 439
floatingfrisbee Avatar asked Apr 18 '11 05:04

floatingfrisbee


3 Answers

Your code seems fine and it should work. I've just tested the following in a new application without problems.

Model:

public class AddressInfo 
{
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Country { get; set; }
}

Controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Check(AddressInfo addressInfo)
    {
        return Json(new { success = true });
    }
}

View:

<script type="text/javascript">
    var ai = {
        Address1: "423 Judy Road",
        Address2: "1001",
        City: "New York",
        State: "NY",
        ZipCode: "10301",
        Country: "USA"
    };

    $.ajax({
        url: '/home/check',
        type: 'POST',
        data: JSON.stringify(ai),
        contentType: 'application/json; charset=utf-8',
        success: function (data) {
            alert(data.success);
        },
        error: function () {
            alert("error");
        }
    });
</script>
like image 112
Darin Dimitrov Avatar answered Nov 15 '22 12:11

Darin Dimitrov


Hi What you need is a ValueProvider.

You can read about ValueProviders here and here.

This ValueProvider picks up posted Json and populates Action method arguments, using the default JavaScriptSerializer

ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());

You can add that line in your Global.asax.cs so that it gets executed once at Application start. You just told the default Model Binder to bind incoming Json to Models. Internally the JsonValueProvider is just a dictionary value provider like the UrlValueProvider, only it constructs the dictionary based on your posted Json. A neat implementation by the MVC team. GJ MVC team.

like image 27
Zasz Avatar answered Nov 15 '22 11:11

Zasz


Thank you for the response above, but the example is not quite correct. Here's what the client-side code should look like:

        jQuery.ajax({
            url: '/Blogs/Update',
            type: "POST",
            data: JSON.stringify(blog),
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            success: function (d) {
                if(d.success == true)
                    jQuery('#status').html('Blog saved');
                else
                    jQuery('#status').html('The server had some issues with the data');
            },

            error: function () {
                jQuery('#status').html('Ajax error occurred during the transmission.');

            }
        });

As you can see, the success function expects an object, not a method, so the code in the previous response produces a syntax error. the request above could pass through ajax successfully but still generate an error on the server. The error function in ajax only appears when an error was generated, either during transmission, or a 500 at the server.

The way the server should handle the above request would look like this (asp.net MVC 2 or 3):

    [Transaction]
    [HttpPost]
    public ActionResult Update(Blog blog)
    {
        if (ModelState.IsValid && blog.IsValid())
        {
            this.blogRepository.SaveOrUpdate(blog);
            return Json(new { success = true });

        }

        return Json(new { success = false });

    }

Thanks,

Tomato

like image 32
aldosa Avatar answered Nov 15 '22 11:11

aldosa