ASP.NET View IEnumerable Item validation

I have this ASP:NET MVC Razor View which has a IEnumerable as model .

I'm creating a table where each line represents a item from the IEnumerable.

I'm using this code:

@foreach (var item in Model)
{
    <tr>
        <td>
            <input type="checkbox" name="selectedFoo" value="@item.isAdded"
               @(Html.Raw(item.isAdded? "checked=\"checked\"" : "")) />
            @item.FooName
        </td>

        <td>
            @Html.EditorFor(modelItem=> item.Name, new { htmlAttributes = new { @class = "form-control", style = "width: 70px" } })
            @Html.ValidationMessageFor(modelItem=> item.Name, "", new { @class = "text-danger" })

        </td>

     </tr>
}

My problem is that when I enter an incorrect value for the "Name" property all the other text input get the validation error.

Solutions?

Thank you.


Best Answer

I would remove '@:' from the table elements. Also using the razor syntax I would generate a form tag. That may have something to do with it. Also add the ValidationSummary method. Is that snippet you posted the complete view?

@using (Html.BeginForm())
{
@Html.ValidationSummary(true, "", new class{@class="text-danger"})
    @foreach (var item in Model)
    {
        <tr>
           <td>
                <input type="checkbox" name="selectedFoo" value="@item.isAdded"
                   @(Html.Raw(item.isAdded? "checked=\"checked\"" : "")) />
                @item.FooName
            </td>

            <td>
                @Html.EditorFor(modelItem=> item.Name, new { htmlAttributes = new { @class = "form-control", style = "width: 70px" } })
                @Html.ValidationMessageFor(modelItem=> item.Name, "", new { @class = "text-danger" })

            </td>
         </tr>
    }
}

If it's a partial view make sure the property 'Name' doesn't exist on any other fields in the view. 'Name' is very generic, perhaps you should rename it something more descriptive. 'FullName', 'ProductName'. ect....

Answer 2

Your foreach loop is generating duplicated name attributes for each textbox, and the ValidationMessageFor() applies to all elements with that name. In addition, you will never be able to bind to you model when you submit your form.

You need to use a for loop or custom EditorTemplate to generate your elements (refer this answer for more detail)

Assuming your model is IList<T>, then

@for(int i = 0; i < Model.Count; i++)
{
    @Html.EditorFor(m => m[i].Name, new { htmlAttributes = new { @class = "form-control", style = "width: 70px" } })
    @Html.ValidationMessageFor(m => m[i].Name, "", new { @class = "text-danger" })
}

In addition, use the CheckBoxFor() method to generate checkboxes (assumes selectedFoo is typeof bool)

@Html.CheckBoxFor(m => m[i].selectedFoo)
@Html.LabelFor(m => m[i].selectedFoo, Model[i].FooName)