I’m having a an odd problem with MVC3 and the model binding.
When I post a JSON object to my controller the model binder can’t create a typed object out of it at all. All the properties are the default (i.e. empty strings)
However if I create an instance on the server, and send it as a JSON action result the data on the wire looks identical.
I’ve tried with
$.ajaxSettings.traditional = true;
and it makes no difference
As an example if I post
{"RoutineName":"My new routine","Routines":[{"DayName":"Monday","Items":[21,31]}]}
The model binder fails, but coming from the server the data looks like
{"RoutineName":"Routine From Code","Routines":[{"DayName":"Monday","Items":[1,2]},{"DayName":"Tuesday","Items":[]}]}
The html used to generate this looks like
$('#submitRoutine').click(function () {
var routines = [];
$('.DayName').each(function (index, item) {
var $item = $(item);
var name = $item.html();
var routineItems = [];
$($item.attr('href')).find('.itemId').each(function () {
routineItems.push(parseInt($(this).val(), 10));
});
routines.push({
DayName: name,
Items: routineItems
});
});
var routine = {
RoutineName: $('#routineName').val(),
Routines: routines
};
$.ajaxSettings.traditional = true;
$.post('/Machine/CreateRoutine', JSON.stringify(routine),function (data) {},'json');
});
So it looks like model binding from a typed object to JSON is ok, but coming back the other way isn’t. Is there something I’ve missed?
The models are in F#
type RoutineDayViewModel() =
let mutable _name = String.Empty
let mutable _items = new ResizeArray<int>()
member x.DayName with get() = _name and set value = _name <- value
member x.Items with get() = _items and set value = _items <- value
type RoutineViewModel() =
let mutable _name = String.Empty
let mutable _routines = new ResizeArray<RoutineDayViewModel>()
member x.RoutineName with get() = _name and set value = _name <- value
member x.Routines with get() = _routines and set value = _routines <- value
EDIT:
I’ve also tried with the following C# classes and get the same result
public class RoutineDayViewModel
{
public string DayName { get; set; }
public List<int> Items{ get; set; }
}
public class RoutineViewModel
{
public string RoutineName { get; set; }
public List<RoutineDayViewModel> Routines { get; set; }
}
I’ve also added the following to the global.asax
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory())
Thanks
You need to set the request content type to
application/jsonif you intend to send a JSON formatted request which is what you are doing with theJSON.stringifymethod. So instead of:you could use:
With this you don’t need to set
$.ajaxSettings.traditionalnor you should be adding anyJsonValueProviderFactoryin your Global.asax as this provider is already added by default in ASP.NET MVC 3.