Model binder does not convert json to IEnumerable<T>

2.9k views Asked by At

I am sending json data to my controller action via jquery ajax post. The IEnumerable in my action is alway null.

Is my json wrong or why does the model binder not convert the json to the IEnumerable ?

public ActionResult Update(IEnumerable<Teststep> teststeps)
{
   //
}

$.ajax({
            url: '@Url.Action("Update", "Teststep")',
            type: 'POST',
            data: [{ "errortext": "oh something bad happended.", "unitid": "10" }, { "errortext": "you got it man.", "unitid": "20"}],
            success: function (response) {
                debugger;
                if (response.success) {
                    dlg.dialog("close");
                    // Update UI

                }
                else {
                    // Reload the dialog with the form to show model/validation errors 
                    dlg.html(response);
                }
            }
        });

public class Teststep
{

 [HiddenInput(DisplayValue = false)]
 public int UnitId { get; set; }    

 public string ErrorText { get; set; }  

 // some other props removed for readability   

}
2

There are 2 answers

0
Elisabeth On

Now it works! I get 1 item in the IEnumerable. The problem was the messed up json ;-)

 var data = { teststeps: [{ ErrorText: 'bla', UnitId: 10}] };
        $.ajax({
            url: '@Url.Action("Update", "Teststep")',
            type: 'POST',
            data: JSON.stringify(data),
            dataType: 'json',
            contentType: 'application/json'            
        });

[HttpPost]
public ActionResult Update(IEnumerable<Teststep> teststeps)
{

}
4
danludwig On

In order to get collections (arrays, ienumerables, etc) to pass correctly through the modelbinder to the action method, I've always had to set the traditional: true option on the ajax call:

$.ajax({
    url: '@Url.Action("Update", "Teststep")',
    type: 'POST',
    traditional: true,
    ...