Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing json list to MVC 3

I am trying to submit this with Ajax to a MVC3 controller:

    var params = {
        'productId': productId,
        'list': []
    };

    $.each($('.specificationId'), function () {
        var specId = $(this).attr('id').replace('specification_', '');

        var specification = {
            specificationId: specId,
            articleId: $('#articleid_' + specId).attr('value'),
            price: $('#price_' + specId).attr('value'),
            stock: $('#stock_' + specId).attr('value'),
            stockCount: $('#stockcount_' + specId).attr('value'),
            weight: $('#weight_' + specId).attr('value'),
            visible: $('#visible_' + specId).attr('checked')
        };

        params.list.add(specification);
    });

    console.log(params);
    //all values are parsed fine here, shows an array with json objects

    $.ajax({
        type: "POST",
        url: "/Admin/Product/Save/",
        data: params,
        success: function () { alert('done'); }
    });

Now this has to go to the controller like so:

    [HttpPost]
    public Boolean Save(Int32 productId, Object[] specifications)
    {

        return true;
    }

But Object[] does not work, returns null, I tried all sorts of stuff like lists of a model etc, but it will stay null.

How to tackle this?

like image 641
Roger Far Avatar asked Jun 19 '11 22:06

Roger Far


3 Answers

ASP.NET MVC 3 includes built-in JSON model binding.

So create simple POCOs which matches the JSON your attempting to submit:

public class ProductJsonModel
{
   public int ProductId { get; set; }
   public ProductSpecificationJsonModel[] @List { get; set; }
}

public class ProductSpecificationJsonModel
{
   public int SpecificationId { get; set; }
   public int ArticleId { get; set; }
   public double Price { get; set; }
   public int Stock { get; set; }
   public int StockCount { get; set; }
   public int Weight { get; set; }
   public bool Visible { get; set; }
}

Then accept that in your action:

[HttpPost]
public Boolean Save(ProductJsonModel model)

As long as the property names in the JSON object match the property names in the POCO's, MVC will bind for you.

Also - you should serialise the JSON using .stringify or something similar, and set the contentType of the $.ajax object accordingly.

like image 154
RPM1984 Avatar answered Nov 17 '22 18:11

RPM1984


Try changing your controller action to (I'm assuming here that Specification is a model representing the JSON you're trying to post):

public Boolean Save(Int32 productId, List<Specification> specifications)

And then change these things in your JS:

var params = {
    'productId': productId,
    'specifications': []
};

params.specifications.add(specification);

$.ajax({
    type: "POST",
    url: "/Admin/Product/Save/",
    data: JSON.stringify(params),
    contentType: 'application/json',
    success: function () { alert('done'); }
});
like image 38
gram Avatar answered Nov 17 '22 18:11

gram


jQuery .ajax() converts the JSON object to a collection of key value pairs in the application/x-www-form-urlencoded content type. You can read a good explanation of this in the blog post and comments of POSTing JSON Data to MVC Controllers

So, You should either create a custom ModelBinder or put FormCollection form as the parameter instead of Object[]. The FormCollection will give you a NameValueCollection of the Form's values that also implements IValueProvider. You can loop through the collection and all your data will be there.

like image 2
smartcaveman Avatar answered Nov 17 '22 18:11

smartcaveman