Consider the following:
Form
<form method="post">
<input name="As[].Id1" />
<input name="As[].Id2" />
<input name="Ids[]" />
</form>
Form Data
As[].Id1=0&As[].Id2=1&As[].Id1=2&As[].Id2=3&Ids[]=4&Ids[]=5
Models
public class A {
public int Id1 { get; set; }
public int Id2 { get; set; }
}
public class B {
public IEnumerable<A> As { get; set; }
public IEnumerable<int> Ids { get; set; }
}
Action Method
[HttpPost]
public ActionResult C(
B b) {...}
In the example above, I expect to have an instance of B
where it's As
property contains two objects: { Id1=0, Id2=1}
, and { Id1=2, Id2=3 }
; and it's Ids
property contains two ints: 4,5
. In reallity, I get an instance of B
where it's As
property is null
and it's Ids
property contains two ints: 4,5
.
So, the binder seems to have a hard time mapping collection properties of complex objects when the form data does not have an index for the collection. If it had an index, that starts at 0
, it binds as expected.
My problem is that my form can't have an index because the amount of postable fields can change at any given point, which is why I want to use an index-less collection which works fine for simple properties.
Is there some way I can make the binder work without going down the road of either 1) normalizing the form before submission with JavaScript to edit all field names and give them an index or 2) writing a custom binder for class B
? I want to avoid the JavaScript route because I don't trust it, and from briefly trying out the custom binder route, it looks like it will be a pain to get to work.