0

I am binding objects in a razor foreach in the index.html:

VIEW

@using (Ajax.BeginForm("Save", "Unit", new AjaxOptions { OnSuccess = "onSuccess" }))
    {

<button type="submit" class="btn btn-default" id="saveUnits"><i class="fa fa-save"></i></button>


    <table>
        <tbody>
            @foreach (var item in Model)
            {
                <tr>

                    @Html.HiddenFor(modelItem => item.UnitId)
                    <td>
                        @Html.EditorFor(modelItem => item.Name)
                    </td>
                    <td>
                        @Html.EditorFor(modelItem => item.ErrorText)
                    </td>

                </tr>
            }
        </tbody>
    </table>
}

I have grabbed the data sent to my action parameter with fiddler and got this:

item.UnitId=5&
item.Name=111111111111&
item.ErrorText=fsdddddddddddddddd+&

item.UnitId=5&
item.Name=+&
item.ErrorText=dddddd+&

ACTION

public ActionResult Save(List<Unit> units )
{
    return new EmptyResult();   
}

VIEWMODEL

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

    [DataType(DataType.MultilineText)]
    public string Name { get; set; }

    [DataType(DataType.MultilineText)]
    public string ErrorText { get; set; 
}

Why is my units instance null? The properties match so they should be bound!

Did I overlook something?

1

1 Answer 1

2

You need to use a for loop not a foreach loop. Also, it would be better to make your Model class have a property which is a collection.

Your model could be something like:

public class UnitsViewModel
{
    public List<Unit> Units { get; set; }

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

        [DataType(DataType.MultilineText)]
        public string Name { get; set; }

        [DataType(DataType.MultilineText)]
        public string ErrorText { get; set; }
    }
}

And you could do the following in your cshtml:

@for (int i = 0; i < Model.Count; i++)
{
    <tr>

        @Html.HiddenFor(m => m.Units[i].UnitId)
        <td>
            @Html.EditorFor(m => m.Units[i].Name)
        </td>
        <td>
            @Html.EditorFor(m => m.Units[i].ErrorText)
        </td>

    </tr>
}
Sign up to request clarification or add additional context in comments.

4 Comments

but why do the razor scaffold tools make it a foreach ?
Get the current element from modelItem[i] and not from Model[i]? That does not make sense. I get an error that I have to use a List because IEnumerable does not know the [] operator. Razor forces me to use Lists??? When I change to a List at the index top site then all my header declations are invalid: @Html.EditorFor(item => item.Name)
stackoverflow.com/questions/14165632/… OK its a technical limitation it must be a for loop with index else it can not bind the correct item...
Had a similar problem the foreach is the culprit.

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.