I hope anyone can help me (Sorry for my english). I have a problem when I want to send un array of arrays in ajax. My model is:
public class SJSonModel
{
public string Name { get; set; }
public bool isChecked { get; set; }
}
public class SJSonModelList
{
public List<SJSonModel> Features { get; set; }
public List<SJSonModel> MenuItems { get; set; }
}
The controller:
[HttpPost]
public ActionResult CheckPreferences(SJSonModelList postData)
{
BindUserFeatures(postData.Features);
return Json(new { status = "Success", message = "Passed" });
}
The View simplified:
<div class="Feature borderRadius Items">
<h2>Title
<input type="checkbox" class="Item" name="featureName"/>
</h2>
<div class="FeatureDetails subItems">
<a href="@Url…">featureName</a>
<input type="checkbox" class="subItem" name="subItemName"/>
</div> <!-- endOf FeatureDetails -->
The JQuery code:
var isChecked = false;
var features = new Array();
var menuItems = new Array();
var postData = new Array();
Here I fill the features, the menuItems with the featureName/menuItemName and isChecked boolean for each feature/menuItem
menuItems.push({ "Name": $(this).attr('name'), "isChecked": isChecked });
features.push({ "Name": $(this).attr('name'), "isChecked": isChecked });
postData.push({ "features": features, "menuItems": menuItems });
postData = JSON.stringify(postData);
The ajax function:
$(':submit').click(function () {
postData.push({ "features": features, "menuItems": menuItems });
postData = JSON.stringify(postData);
$.ajax({
url: '@Url.Action("CheckPreferences")',
type: 'POST',
data: postData,
contentType: "application/json; charset=utf-8",
dataType: "json",
traditional: true,
success: function () { window.alert('@Resource.AjaxSuccess'); },
error: function (event, request, settings) { window.alert('@Resource.AjaxError' + ' : ' + settings); },
timeout: 20000
}); //endOf $.ajax
}); //endOf :submit.click function
When I do alert(postData), in client side it contains the true values for each item but in the conroller the postData.Features and postData.MenuItems are null.
I have tried to pass just one array to the controller too:
features = JSON.stringify(features);
in $.ajax:
{… data: features,…}
in controller:
ActionResult CheckPreferences(IEnumerable<SJSonModel> features)
and it works fine, but I don't know how to pass the array of json objects to my contoller. So I hope to retrieve the answer here :)
Thank you very much.
Since you are passing serialized data from the client define postData as type string in your controller and then use JavascriptSerializer.Deserialize to deserialize the JSON into your object. This way you can also catch any errors that may occur during deserialization and debug the JSON that is sent over. One thing I am not sure if is if the Deserializer expects to match field names on case sensitivity. You define your arrays in the Model as "Features" and "MenuItems" whereas in the Javascript they are defined as "features" and "menuItems".
Instead of combining your arrays into another array, you're best of sending them as individual parameters to the action method, something like:
Assume we still have your two arrays:
Then in your JQuery ajax call do the following:
Then your controller method should be:
I also edited your classes by putting in a constructor to work with the above code, like so: