asp.net mvc5验证对象列表

时间:2015-01-24 03:26:58

标签: asp.net-mvc validation asp.net-mvc-5 unobtrusive-validation

我有一个视图,可以在列表中的每个项目上输入交货数量,并将对象列表发送回控制器。我想验证页面上的所有文本框,并在模型中添加了注释。

问题是,我只能验证第一行(也在输出html中只有第一行有验证标记)。由于在第一行上生成了验证,所以我不认为它与模型有关。有没有办法在所有行中生成验证?如果没有,有哪些解决方法?

    @{int i = 0;}
    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.HiddenFor(modelItem => item.eo, new { Name = "[" + i + "].eo" })
                @Html.DisplayFor(modelItem => item.barcode)
                @Html.Hidden("[" + i + "].barcode", Model[i].barcode)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.itemno)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.cdesc)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.acost)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.qty)
            </td>
            <td>
                @Html.EditorFor(modelItem => item.dqty, new { htmlAttributes = new { Name = "[" + i + "].dqty", id = "[" + i + "].dqty", @class = "form-control" } })
                @Html.ValidationMessage("[" + i + "].dqty", "", new { @class = "text-danger" })
            </td>
        </tr>
        i++;
    }

这是第一行中文本框生成的html。

<input Name="[0].dqty" class="form-control text-box single-line" data-val="true" data-val-number="The field 出貨數量 must be a number." data-val-required="必須填上出貨數量" id="[0].dqty" name="item.dqty" type="text" value="10" />
<span class="field-validation-valid text-danger" data-valmsg-for="[0].dqty" data-valmsg-replace="true"></span>

第二排起......

<input Name="[1].dqty" class="form-control text-box single-line" id="[1].dqty" name="item.dqty" type="text" value="7" />
<span class="field-validation-valid text-danger" data-valmsg-for="[1].dqty" data-valmsg-replace="true"></span>

模特

[MetadataType(typeof(EorderDetailsMetaData))]
public partial class EorderDetails
{
    public string eo { get; set; }
    public string barcode { get; set; }
    public string itemno { get; set; }
    public string cdesc { get; set; }
    public Nullable<decimal> qty { get; set; }
    public Nullable<decimal> dqty { get; set; }
    public Nullable<decimal> acost { get; set; }
    public string sdate { get; set; }
    public string edate { get; set; }
    public string shop { get; set; }
    public string sname { get; set; }
    public string saddr { get; set; }
    public string shoptel { get; set; }
    public string shopfax { get; set; }
}

public class EorderDetailsMetaData
{
    [Display(Name = "訂單編號")]
    public string eo { get; set; }
    [Display(Name = "電腦條碼")]
    public string barcode { get; set; }
    [Display(Name = "貨品編號")]
    public string itemno { get; set; }
    [Display(Name = "貨品名稱")]
    public string cdesc { get; set; }
    [Display(Name = "訂購數量")]
    [DisplayFormat(DataFormatString = "{0:n0}", ApplyFormatInEditMode = true)]
    public Nullable<decimal> qty { get; set; }
    [Display(Name = "出貨數量")]
    [DisplayFormat(DataFormatString = "{0:n0}", ApplyFormatInEditMode = true)]
    [Required(ErrorMessage = "必須填上出貨數量")]
    public Nullable<decimal> dqty { get; set; }
    [Display(Name = "成本價")]
    [DisplayFormat(DataFormatString = "{0:0.##}", ApplyFormatInEditMode = true)]
    public Nullable<decimal> acost { get; set; }
    public string sdate { get; set; }
    public string edate { get; set; }
    public string shop { get; set; }
    public string sname { get; set; }
    public string saddr { get; set; }
    public string shoptel { get; set; }
    public string shopfax { get; set; }

}

2 个答案:

答案 0 :(得分:1)

您应该在for循环中生成集合,让助手为您生成正确的html。如果你检查了你在第二个片段中发布的html,你会看到问题(两个name属性!)

@model IList<EorderDetails>
@using(Html.BeginForm())
{
  for(int i = 0; i < Model.Count; i++)
  {
    @Html.HiddenFor(m => m[i].eo)
    @Html.DisplayFor(m => m[i].barcode)
    ....
    @Html.EditorFor(m => m[i].dqty, new { htmlAttributes = new { @class = "form-control" } })
    @Html.ValidationMessageFor(m => m[i].dqty, new { @class = "text-danger" })
  }
  <input type="submit" />
}

或者,您可以为模型创建自定义EditorTemplate

/Views/Shared/EditorTemplates/EorderDetails.cshtml

@model EorderDetails
@Html.HiddenFor(m => m.eo)
@Html.DisplayFor(m => m.barcode)
....

并在主视图中

@model IList<EorderDetails>
@using(Html.BeginForm())
{
  @Html.EditorFor(m => m)
  <input type="submit" />
}

答案 1 :(得分:0)

要省略这种奇怪的行为,应该:

  1. 将属性定义为 Array,而不是 ICollection 或 IList。
  2. 应该在 cshtml 中使用 for,而不是 forEach。

不知道为什么这会导致差异。但我认为不应该。而且我认为这是一个应该修复的错误。