up vote 5 down vote favorite
2
share [g+] share [fb]

I am on ASP.Net MVC 3, and going by the feature list supported in at, i should be able to get default json model binding working out of the box. However i havent been successful in binding an array/collection from json to the action method parameter. Although I did get simple json object binding working right. Would greatly appreciate if an expert here could tell me what i am doing wrong.

Here is the code:

Server side code first:

//Action Method

 public JsonResult SaveDiscount(IList<Discount> discounts)
    {
       foreach(var discount in discounts)
       {
       ....
       }
    }

//View model

public class Discount
{
    string Sku{get; set;}
    string DiscountValue{get; set;}
    string DiscountType{get; set;}

}

//client side(jquery/js):

    var discount = {};
    var jsondatacoll = [];
    $('#discountgrid tr').each(function () {

        sku = $(this).find("td").eq(1).html();
        discValue = $(this).find('.discval').val();
        discType = $(this).find('.disctype').val();

        discount = { Sku: sku, DiscountType: discType, DiscountValue: discValue};
        jsondatacoll.push(discount);
        }
    })
    if (jsondatacoll.length > 0) {
        var catalogDiscount = JSON.stringify(jsondatacoll);

        $.ajax(
        {
            url: '/url/savediscount',
            type: 'POST',
            data: catalogDiscount,
            dataType: 'json',
            contentType: 'application/json; charset=utf-8',
            success: function (data, textStatus, jqXHR) {
                ...                   
            },
            error: function (objAJAXRequest, strError) {                 
               ...
            }
        }
     );   //ajax
    }

i did check the json payload in fiddler and it look like below:

[
    {"Sku":"sku1","DiscountType":"type1","DiscountValue":"10"},     
    {"Sku":sku2","DiscountType":"type1","DiscountValue":"12"}, 
    {"Sku":"sku3","DiscountType":"type2","DiscountValue":"40"}
]

And on the server side i do see the IList<Discount> discounts has been populated with 3 empty Discount objects - meaning the properties are null but the length of the discounts argument is 3.

link|improve this question

9  
Your model's properties should be marked public. Typo or oversight? – Crescent Fresh Mar 12 '11 at 18:49
wow man! that was an oversight!!! would you want to enter this as answer so that i can mark it? :) – thanikkal Mar 12 '11 at 18:55
1  
Thanks to the rest of your post being correct (other than those missing 'publics'), I noticed the contentType being set along with using JSON.stringify and it made all the difference. Struggled with this for hours! Thanks! – Daniel Gill Sep 19 '11 at 18:10
feedback

2 Answers

Your code looks fine.. But check this

  1. Routing settings.
  2. Put [HttpPost] attribute on SaveDiscount

and try this

var catalogDiscount = JSON.stringify( { discounts: jsondatacoll } );

that would give make right data binding.

link|improve this answer
thanks for answering here. as explained in the comments above, i missed marking my viewmodel properties public. – thanikkal Mar 14 '11 at 2:24
feedback
up vote 5 down vote accepted

As Cresnet Fresh rightly pointed out in the comments to the question the model properties must be marked public.

So modifying Discount class as below resolved this.

public class Discount
{
    public string Sku{get; set;}
    public string DiscountValue{get; set;}
    public string DiscountType{get; set;}

}
link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.