Passing knockout.js observablearray object to MVC Controller Action?
Try sending it as a JSON request by specifying the correct request Content-Type header:
updateAccessLevels = function () {
$.ajax({
url: '/DataService/UpdateAccessLevels',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(viewModel.AccessLevels),
success: function(status) {
alert(status);
}
});
};
Related videos on Youtube
![ccorrin](https://i.stack.imgur.com/GhuGC.jpg?s=256&g=1)
ccorrin
Updated on September 15, 2022Comments
-
ccorrin almost 2 years
Im using knockout with MVC. Im trying to pass an observable array of objects from knockout back to my MVC controller action for saving to the database. If I pass the Array from knockout over to my controller action via ko.toJSON(viewModel.ArrayName) it comes back as null in my controller parameter. If I try to pass it to MVC via ko.toJS(viewModel.ArrayName) it has the correct number of items but the data is null for some reason. Any help on how to do this would be greeatly appreciated. Thanks!
My JQuery Data Retrieval Method:
var dataService = {}; var viewModel; $(document).ready(function () { dataService.getAccessLevelList(); }) dataService.getAccessLevelList = function () { $.post('/DataService/GetAccessLevelList', null, function (data) { viewModel = ko.mapping.fromJS(data); ko.applyBindings(viewModel); }); }
This is the problem method:
updateAccessLevels = function () { $.post('/DataService/UpdateAccessLevels', { accessLevels: ko.toJSON(viewModel.AccessLevels) }, function (status) { alert(status); }); }
My MVC Controller Data Retrieval action:
[HttpPost] public ActionResult GetAccessLevelList() { FacilityAccessViewModel viewModel = new FacilityAccessViewModel(); viewModel.AccessLevels = unitOfWork.AccessLevelRepository.Get().ToList(); return Json(viewModel); }
The parameter is coming back NULL or with NULL data when trying to pass it in from Knockout on this controller method.
[HttpPost] public ActionResult UpdateAccessLevels(List<AccessLevel> accessLevels) { try { foreach (AccessLevel record in accessLevels) { unitOfWork.AccessLevelRepository.Update(record); } unitOfWork.Save(); return Json("SUCCESS"); } catch (Exception ex) { return Json(ex.ToString()); } }
Below is the JSON data shown via fiddler thats being posted to my MVC controller action when i pass in { accessLevels: ko.toJSON(viewModel.AccessLevels) } the controller parameter is coming in null using this
[{"Access":[],"Id":1,"AccessLevelDesc":"TEST222"},{"Access":[],"Id":2,"AccessLevelDesc":"TEST222"}]
Below is the JS data shown via fiddler thats being posted to my MVC controller action when i pass in { accessLevels: ko.toJS(viewModel.AccessLevels) }, in this case the list has two members as expected, but the data is all null in the properties
accessLevels[0][Id] 1 accessLevels[0][AccessLevelDesc] TEST222 accessLevels[1][Id] 2 accessLevels[1][AccessLevelDesc] TEST222
If I pass in a single object to my controller it works just fine, but I cant seem to figure out the proper way to post an array of objects to my controller from an obervablearray back to a POCO entity.
-
Brian Ball over 11 yearsWhat is the shape of the JSON that is being posted? Either use the debugger to get this or use Fiddler to capture it, then update your post with this information. Thanks!
-
-
ccorrin over 11 yearsThis worked perfectly. Thank you. So trying to understand this, why did it come through as null without manually specifying the content type?
-
Darin Dimitrov over 11 yearsBecause you are sending JSON string and haven't specified the content type. The default model binder has strictly no clue how to bind it. You could have passed
{ accessLevels: viewModel.AccessLevels }
without calling anyko.toJSON
but this would have worked only with primitive types inside the array. With more complex types it's better to use a JSON request. -
ccorrin over 11 yearsThat makes sense, as when I send in one item rather than an array it worked fine. Thank you Darin.
-
ViqMontana almost 6 yearsThis catches me out every time, I always forget to include the
contentType: 'application/json; charset=utf-8',
!