1

I am trying to send a form array of data my server but it not binding correctly.

public class PersonViewModel
{
    public List<Person> Persons {get; set}
}

public class Person{
    public string FirstName {get; set;}
}
   
// view model that wil render all the partial view models showing all the people 
@using (Html.BeginForm("Action", "Controller", FormMethod.Post, new { id="people-form" autocomplete = "off" }))
{
    <div class="container">
       @for (int i = 0; i < Model.Persons.Count; i++)
        {
            <div>
                <label>
                    @Html.TextBoxFor(x => x.Persons[i].FirstName)
                </label>
            </div>
        }
    </div>  
}

// ajax used to post, trying to serialize it as an array but still when it hits my action it is not binding.
return $.ajax({
    method: 'POST',
    url: 'SavePeople',
    data: $('#people-form').serializeArray(),
}).done(function (response) {

}).fail(function (err) {
    
});

[HttpPost]
public JsonResult SavePeople(PersonViewModel vm /* this comes in as null */)
{

}

The data getting sent looks like Persons[0].FirstName: 41441 but for some reason it is trying to bind it directly into the PersonViewModel instead of adding it to the Persons Collection.

defines
  • 10,229
  • 4
  • 40
  • 56
chobo2
  • 83,322
  • 195
  • 530
  • 832
  • btw you should send something like { persons: [ firstName: 'test']} – ale Aug 15 '20 at 05:26
  • There is no json sent really, I am serializing the entire form which produces Persons%5B0%5D.FirstName=55353 if this was not in a collection it would bind but being a collection is causing problems. – chobo2 Aug 15 '20 at 05:30

3 Answers3

0

It looks like this suffers from the same bug identified in ASP.NET MVC Model Binding with jQuery ajax request

There is a bug in MVC they refuse to fix that if the colection property name begins with the type name it does not bind.

Try changing:

public class PersonViewModel
{
    public List<Person> Persons {get; set}
}

To:

public class PersonViewModel
{
    public List<Person> People {get; set}
}

Try this; if you're still having trouble post below and I'll assist.

defines
  • 10,229
  • 4
  • 40
  • 56
  • Hey, it seems to still not be working. I changed my code to reflect your changes buts till null in the binding. The data being sent now looks like Persons[0].FirstName – chobo2 Aug 17 '20 at 16:43
  • 1
    Sounds like you also need to change in the view - Model.People instead of Model.Persons – defines Aug 17 '20 at 17:03
0

First of all, please make sure your ajax is working.

return $.ajax({
    contentType: 'application/json; charset=utf-8',
    url: DeploymentPath + '/ControllerName/ActionName',
    type: "POST",
    data: JSON.stringify({ "parameterName": _input})
});

Variable References to your project

  • DeploymentPath : url to your project
  • ControllerName : controller name of your SavePeople() function
  • ActionName: SavePeople
  • parameterName: vm
  • _input: your Person objects

Once, your ajax function is able to execute, you can directly access the value in your SavePeople action, using vm.Persons - which is a List.

WenJun
  • 69
  • 1
  • 11
0

assuming that you haven't customized serialization settings and model is @model HomeController.PersonViewModel. The following expresssion works

@Html.TextBoxFor(x => @Model.Persons[i].FirstName)

if nothing works just use IFormCollection and parse values manually or for debugging the specific issue in Model Binding.

public JsonResult SavePeople(IFormCollection vm)
Mujahid Daud Khan
  • 1,983
  • 1
  • 14
  • 23