问题
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.
回答1:
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;}
}
回答2:
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.
回答3:
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