验证IEnumerable视图中的部分视图

时间:2012-12-27 21:34:54

标签: asp.net-mvc jquery jquery-validate partial-views

我有一个可以呈现可编辑数据表的视图。该页面具有Ajax控件,允许您在表上添加和删除单个行。我使用强类型视图来实现这一点,该视图具有从IEnumerable派生的模型。在视图中,它循环遍历模型中的每个项目,并使用强类型的部分视图呈现它。通过这种方式,控制器可以使用父视图来呈现整个列表,并且Ajax端点可以使用局部视图来呈现并返回一个表行,以便jQuery插入到表中。

单击保存按钮时,jQuery循环遍历表,打包数据并分配序号,以便在将数据发布到服务器时,模型绑定引擎将数据识别为IEnumerable<TimeLogEntry>。 / p>

这是我的列表视图(删除了不必要的代码):

@model IEnumerable<TimeTracker.Models.TimeLogEntry>

<table id="time-log">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.FirstOrDefault().StartTime)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.FirstOrDefault().EndTime)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.FirstOrDefault().Description)
            </th>
        </tr>
    </thead>

    <tbody>
        foreach (var item in Model.OrderByDescending(entry => entry.StartTime))
        {
            Html.RenderPartial("~/Views/TimeLog/_EditEntry.cshtml", item);
        }
    </tbody>
</table>

显示单个TimeLogEntry的部分视图:

@model TimeTracker.Models.TimeLogEntry

<tr id="@Model.TimeLogEntryId">
    <td class="no-wrap">
        @Html.EditorFor(model => model.StartTime)
        @Html.ValidationMessageFor(model => model.StartTime)
    </td>
    <td class="no-wrap">
        @Html.EditorFor(model => model.EndTime)
        @Html.ValidationMessageFor(model => model.EndTime)
    </td>
    <td>
        @Html.EditorFor(model => model.Description)
        @Html.ValidationMessageFor(model => model.Description)
    </td>
</tr>

此代码未正确验证,因为呈现它的部分视图与项目来自的IEnumerable分离,因此不知道它在foreach循环的上下文中执行。因此,每个表行中的元素将具有相同的名称和ID,这会导致客户端验证出现问题。例如,所有StartTime文本框的ID都为StartTime,而不是[0].StartTime[1].StartTime等.EdowFor方法无法设置{{1 }或id属性。如何使每个文本框data-valmsg-for属性唯一,并且每个验证邮件上的id属性与其对应的文本框ID匹配?我还有另一种更好的方法吗?

1 个答案:

答案 0 :(得分:0)

您可以将视图重新定义为(不使用“部分”)

@model IEnumerable<TimeTracker.Models.TimeLogEntry>
<table id="time-log">
    ...other stuff that you want to add 
    <tbody>
        @{var itemList = Model.OrderByDescending(entry => entry.StartTime).ToList(); }
        @for(var index =0 ; index < itemList.Count;index ++)
        {
           <tr id="@Model.TimeLogEntryId">
             <td class="no-wrap">
                @Html.EditorFor(model => model[index].StartTime)
                @Html.ValidationMessageFor(model => model[index].StartTime)
            </td>
            <td class="no-wrap">
               @Html.EditorFor(model => model[index].EndTime)
               @Html.ValidationMessageFor(model => model[index].EndTime)
            </td>
            <td>
               @Html.EditorFor(model => model[index].Description)
               @Html.ValidationMessageFor(model => model[index].Description)
            </td>
          </tr>
        }
    </tbody>
</table>