It seems that internal System.Web.PrefixContainer class was introduced in MVC4 and this class has the bug, which is reproduced with the following model, view and controller action method:
public class Model
{
public Model()
{
Value = new List<Item>();
}
public string SomeData { get; set; }
public string ValueIsSequence { get; set; }
public class Item
{
public string Data { get; set; }
}
public List<Item> Value { get; set; }
}
@using (Html.BeginForm())
{
<input type="text" name="SomeData" value="123" />
<input type="text" name="ValueIsSequence" value="True" />
<input type="text" name="Value[0].Data" value="ABC" />
<button type="submit">OK</button>
}
[HttpPost]
public ActionResult Testing(Model model)
{
var failed = model.Value.Count == 0;
return View();
}
The bug is that Model.Value list is empty and "Value[0].Data" form field is skipped. Prefix matching fails while checking "Value" prefix (for the Model.Value property) and probing "ValueIsSequence" field in binary search: "Value" is not equal to "ValueIsSequence" of course, and then the PrefixContainer supposed (incorrectly) that field can only be "Value." or ""Value[", but it detects "ValueIsSequence" that does not match "Value." nor "Value[", the comparer returns -1 (less) and binary search is moving to less half to probing "SomeData" field. So the binary search never detects "Value[0].Data" and Model.Value stays not filled.
Renaming "ValueIsSequence" to "IsSequence" for example, is a possible workaround.
Comments: also worked for me and also worked around it by renaming the field
public class Model
{
public Model()
{
Value = new List<Item>();
}
public string SomeData { get; set; }
public string ValueIsSequence { get; set; }
public class Item
{
public string Data { get; set; }
}
public List<Item> Value { get; set; }
}
@using (Html.BeginForm())
{
<input type="text" name="SomeData" value="123" />
<input type="text" name="ValueIsSequence" value="True" />
<input type="text" name="Value[0].Data" value="ABC" />
<button type="submit">OK</button>
}
[HttpPost]
public ActionResult Testing(Model model)
{
var failed = model.Value.Count == 0;
return View();
}
The bug is that Model.Value list is empty and "Value[0].Data" form field is skipped. Prefix matching fails while checking "Value" prefix (for the Model.Value property) and probing "ValueIsSequence" field in binary search: "Value" is not equal to "ValueIsSequence" of course, and then the PrefixContainer supposed (incorrectly) that field can only be "Value." or ""Value[", but it detects "ValueIsSequence" that does not match "Value." nor "Value[", the comparer returns -1 (less) and binary search is moving to less half to probing "SomeData" field. So the binary search never detects "Value[0].Data" and Model.Value stays not filled.
Renaming "ValueIsSequence" to "IsSequence" for example, is a possible workaround.
Comments: also worked for me and also worked around it by renaming the field