Reputation: 7285
I'm having trouble getting a model to bind on my action when I post from ajax (via jquery).
Model:
public class NoteEditViewModel
{
public bool AddMode { get; set; }
public int ID { get; set; }
public int PersonID { get; set; }
public string Note { get; set; }
public NoteEditViewModel()
{
}
}
Action:
[HttpPost]
public ActionResult Edit(NoteEditViewModel note)
{
...
}
JS: (actually typescript)
$.ajax({
url: this.options.editUrl,
method: 'POST',
data: JSON.stringify(this.convertFormToJSON(this.options.noteFormElement)),
//data: $(this.options.noteFormElement).serialize(),
//data: JSON.stringify({
// AddMode: $("#AddMode").val(),
// ID: $("#ID").val(),
// PersonID: $("#PersonID").val(),
// Note: $("#Note").val()
//}),
//dataType: 'json',
//traditional:true,
//contentType: 'application/json; charset=utf-8',
success: (partialResult) => {
this.options.noteModalElement.modal('hide');
}
});
convertFormToJSON(form : JQuery) {
var array = form.serializeArray();
var json = {};
jQuery.each(array, function () {
json[this.name] = this.value || '';
});
return json;
}
You can see what I've tried here. The action would either receive an empty instance of the model or null.
I did managed to get this to work with a custom ModelBinder, thus:
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var body = controllerContext.RequestContext.HttpContext.Request.Form[0];
var model = JsonConvert.DeserializeObject<NoteEditViewModel>(body);
return model;
}
This may not be the best/safest, but at least it works.
I cant see what I've done wrong here but creating a model binder for each model seems crazy. Non-ajax posts seem to work fine.
Thanks
Upvotes: 2
Views: 6693
Reputation:
You do not need a custom ModelBinder
. Your values will be successfully submitted using
$.ajax({
url: this.options.editUrl,
method: 'POST',
data: $('form').serialize(),
success: (partialResult) => {
this.options.noteModalElement.modal('hide');
}
});
The reason your model is not binding in the POST method is because the name of your parameter (note
) is also the name of a property in your model and the DefaultModelBinder
sets the value of property Note
to the posted value, but also attempts to set the instance of NoteEditViewModel
to that value (a string
) which fails and the model becomes null
Change the signature of the method to
[HttpPost]
public ActionResult Edit(NoteEditViewModel model)
and you model will be correctly bound
Upvotes: 4