【发布时间】:2017-07-19 21:42:20
【问题描述】:
我正在尝试使用数据注释将验证添加到我的模型中不能为空的列表中。我尝试了几种自定义属性的实现,包括here 和here。
我的看法:
<div class="form-group">
@* Model has a list of ints, LocationIDs *@
@Html.LabelFor(model => model.LocationIDs, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<select class="select2 form-control" multiple id="LocationIDs" name="LocationIDs">
@* Adds every possible option to select box *@
@foreach (LocationModel loc in db.Locations)
{
<option value="@loc.ID">@loc.Name</option>
}
</select>
@Html.ValidationMessageFor(model => model.LocationIDs, "", new { @class = "text-danger" })
</div>
</div>
型号:
public class ClientModel
{
public int ID { get; set; }
[Required] // Does nothing
public List<int> LocationIDs { get; set; }
}
控制器:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,LocationIDs")] ClientModel clientModel)
{
if (ModelState.IsValid)
{
db.Clients.Add(clientModel);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(clientModel);
}
我尝试过的(功能相同的)属性之一:
[AttributeUsage(AttributeTargets.Property)]
public sealed class CannotBeEmptyAttribute : RequiredAttribute
{
public override bool IsValid(object value)
{
var list = value as IEnumerable;
return list != null && list.GetEnumerator().MoveNext();
}
}
目前,检查 null 或空列表会通过验证,即使没有选择任何内容。在这种情况下,包含第一个选项的长度为 one 的列表被绑定。
我已经确认控制器实际上发送了一个长度为 1 的 List。但是,我不确定如何改变这种行为。我仍然认为这可能是下面块引用中描述的内容。
我认为我的问题可能在this answer's edit 中有所描述,但我不确定如何解决。
摘录如下:
您还必须小心在视图中绑定列表的方式。 例如,如果您将 List 绑定到这样的视图:
<input name="ListName[0]" type="text" />
<input name="ListName[1]" type="text" />
<input name="ListName[2]" type="text" />
<input name="ListName[3]" type="text" />
<input name="ListName[4]" type="text" />
MVC 模型绑定器将始终在您的 列表,所有 String.Empty。如果这是您的视图的工作方式,那么您的属性 需要变得更复杂一些,例如使用反射拉 泛型类型参数并将每个列表元素与 default(T) 什么的。
【问题讨论】:
-
您是要验证最终用户是否选择了
select中的项目,还是要验证model.LocationIDs中是否有条目,或两者兼而有之? -
两者,我想。客户端是
select,服务器端是model.LocationIDs。我对自动验证属性没有 100% 的透彻理解,但我知道数据注释可以防止保存无效值(必不可少),同时还会向最终用户提供错误消息。 -
@mjwills 我如何编辑我的问题以使其更清楚?
-
我怀疑
ValidationMessageFor可能会帮助您处理前者(选择一个项目),但不能帮助您处理后者(其中有条目)。 -
如果你想了解valdation,那么我建议你从The Complete Guide To Validation In ASP.NET MVC 3 - Part 2开始
标签: c# asp.net asp.net-mvc entity-framework