【问题标题】:selectlistitem validation message not kick in once form is submitted提交表单后,selectlistitem 验证消息不会启动
【发布时间】:2015-04-09 15:50:30
【问题描述】:

我不明白为什么在我提交表单后验证没有启动。

我有这个虚拟机。

public EditFooDetailVm {
  public int FooDetailIdVm { get; set; }

  public IEnumerable<EditFooVm> Foos { get; set; }
}

public class EditFooVm {
  public int FooId { get; set; }
  public int FooDropDownId { get; set; }
  public int Index { get; set; }

  public IEnumerable<SelectListItem> FooDropDown { get; set; }
}

在我的控制器中:

var foo = _db.Foos
             .Select((f, i) => new EditFooDetailVm {
                 FooDetailIdVm = f.FooDetailId,
                 Foos = f.Foos
                         .Select(fs => new EditFooVm {
                             FooId = fs.FooId,
                             Index = i,
                             FooDropDown = fs.FooDropDown.ToSelectList(fd => fd.Name, fd => fd.Id)
                           })
               })

在我看来:

@Model.FooDetailIdVm
@foreach(var item in Model.Foos) {
  @Html.DropDownList("Foos[" + item.Index + "].FooDropDownId", item.FooDropDown, "Please select")
  <span class="field-validation-error" data-valmsg-for="Foos[@item.Index].FooDropDownId" data-valmsg-replace="true"></span>
}

我已经在页面中包含了validationjs,但是一旦我提交了表单,即使我没有在下拉列表中选择任何内容,验证也不会显示在客户端。我什至让自己在渲染验证标签时手动创建标记。我错过了什么?任何帮助将非常感激。谢谢!

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-4 unobtrusive-validation


    【解决方案1】:

    以这种方式使用 foreach 循环不会为您的模型提供正确的 2 路绑定。您通常需要for 循环或自定义EditorTemplate,但在集合中使用DropDownList() 的情况下,您需要EditorTemplate。删除Index 属性并将FooDropDown 更改为typeof SelectList

    public class EditFooVm {
      public int FooId { get; set; }
      [Required(ErrorMessage = "Please select a foo")]
      public int FooDropDownId { get; set; }
      public SelectList FooDropDown { get; set; }
    }
    

    在控制器中

    var foo = _db.Foos.Select(f => new EditFooDetailVm
    {
      FooDetailIdVm = f.FooDetailId,
      Foos = f.Foos.Select(fs => new EditFooVm
      {
        FooId = fs.FooId,
        // Add FooDropDownId = ?? if you want to preselect an option
        FooDropDown = new SelectList(fs.FooDropDown, "Id", "Name")
      })
    })
    

    并为 typeof EditFooVm 创建自定义 EditorTemplate

    /Views/Shared/EditorTemplates/EditFooVm.cshtml

    @model EditFooVm
    @Html.DropDownListFor(m => m.FooDropDownId, Model.FooDropDown, "Please select")
    @Html.ValidationMessageFor(m => m.FooDropDownId)
    @Html.HiddenFor(m => m.FooId) // ??
    

    然后在主视图中

    @Model.FooDetailIdVm
    @using(Html.BeginFor())
    {
      @Html.HiddenFor(m => m.FooDetailIdVm) // ??
      @Html.EditorFor(m => m.Foos)
      ...
    }
    

    Html.EditorFor() 助手将正确呈现您的集合并为您提供 2 路绑定。

    旁注:不清楚,但如果您的查询为每个下拉列表生成相同的选择列表,那么这不是有效的,您应该生成一个选择列表(并将其分配给EditFooDetailVm 中的属性)。如果是这种情况,您可以使用其他视图数据将该选择列表传递给EditorTemplate

    主视图

    @Html.EditorFor(m => m.Foos, new { FooList = Model.FooDropDown})
    

    在模板中

    @Html.DropDownListFor(m => m.FooDropDownId, (SelectList)ViewData["FooList"], "Please select")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-06
      • 2016-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多