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.
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;}
}
while @thanikkal answered this particular question, I had the same symptoms and a very similar setup.
instead of the public
or { get; set; }
in my models causing the model binding to not work it was actually my jQuery method! (RAWR!)
I was using $.post
(which didn't work) instead of $.ajax
.
Doesn't Work:
$.post("/Games/Action", { "userId": "1", "listName": [ { "fooId": "2", "barId": "99" } ] }, 'json', true );
The values are in the Form.Data[], but are not mapped properly.
Works:
$.ajax( { url: '/Games/Action', type: 'POST', data: JSON.stringify({ userId: "1", listName: [ { fooId: 2, barId: 99 } ] }), dataType: 'json', contentType: 'application/json; charset=utf-8', success: function (data, textStatus, jqXHR) { console.log(data); }, error: function (objAJAXRequest, strError) { console.log(data); } });
All values mapped correctly.
Lost a few hours to this one, hope this helps others.
Your code looks fine.. But check this
- Routing settings.
- Put [HttpPost] attribute on SaveDiscount
and try this
var catalogDiscount = JSON.stringify( { discounts: jsondatacoll } );
that would give make right data binding.
来源:https://stackoverflow.com/questions/5284613/asp-net-mvc-3-json-model-binding-to-array