4

I have the following code, only the first form submits anything, the following submit null values, each model has data. If I change it to just one large form, everything submits. Why do the other individual forms post null values?

View

@model myModel[]
<ul>
    @for (int i = 0; i < Model.Length; i++)
    {
        using (Html.BeginForm("controllerAction", "Controller", FormMethod.Post,
                               new { id="Form"+i }))
        {
            <li>
                @Html.TextBoxFor(a => a[i].property1)
                @Html.CheckBoxFor(a => a[i].property2)
                @Html.HiddenFor(a => a[i].property3)
                <input type="submit" />
            </li>
        }
    }
</ul>

Controller

[HttpPost]
public ActionResult controllerAction(myModel[] models)
{
    ...do stuff...
}
2
  • only form that contains clicked submit button submited to server Commented Aug 14, 2015 at 12:16
  • @ConvertToInt32 That is only happening with the first form, and the first submit button, the following forms post null values when their submit buttons are clicked. Commented Aug 14, 2015 at 12:18

1 Answer 1

8

The reason is that your creating form controls with indexers in your for loop, and your POST method parameter is myModel[] models.

By default, the DefaultModelBinder requires collection to be zero based and consecutive, so if you attempt to submit the second form, your posting back [1].property1: someValue etc. Because the indexer starts at 1, binding fails and the model is null.

You can solve this by adding a hidden input for an Index property used by the model binder to match up non consecutive indexers

<li>
    @Html.TextBoxFor(a => a[i].property1)
    @Html.CheckBoxFor(a => a[i].property2)
    @Html.HiddenFor(a => a[i].property3)
    <input type="hidden" name="Index" value="@i" /> // add this
    <input type="submit" />
</li>
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you sir, this is saving me big time!
if you collection is child collection then name should be name ="childvarname.index" where childvarname is name of property for child collection in your variable

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.