嗨,我对ASP.NET MVC控制器中的ModelState有疑问。
当用户从视图中选择某个选项时,“认证”的开始日期和结束日期将根据输入的其他日期进行设置。
这个问题是认证日期返回为null,我们的CertificationMetaData类将字段指定为[Required],因此一旦操作加载,ModelState就无效。
手动删除ModelSate错误允许这个工作,但我想知道是否有更好的方法来做到这一点?有没有办法刷新ModelState?我应该不要求这些字段吗?或者我应该使用javascript从视图中添加日期值吗?
public ActionResult Create(FormCollection fc, Certification certification, Absence absence)
{
if (certification.CertificationTypeID == 1)
{
certification.CertificationStartDate = absence.StartDate;
certification.CertificationEndDate = absence.StartDate.AddDays(7);
this.ModelState.Remove("CertificationStartDate");
this.ModelState.Remove("CertificationEndDate");
}
if (this.ModelState.IsValid)
{
// save
return RedirectToAction("Index");
}
return View();
}
另外,您可以看到我已经对认证类型的ID值进行了硬编码。将值与查找表值进行比较的最佳方法是什么? enum是最好的方式吗?
由于
答案 0 :(得分:33)
以下方法刷新模型状态,并允许您使模型设计与[required]属性等保持一致。
在我的情况下,我希望我的模型有一个必需的字段,正常级别的用户使用API无法更改,所以我已经这样做了:
ModelState.Remove("ChangeDate");
ModelState.Add("ChangeDate", new ModelState());
ModelState.SetModelValue("ChangeDate", new ValueProviderResult(club.ChangeDate, DateTime.Now.ToString(), null));
这样您就不需要删除必填字段了,也不需要在javascript中提供日期。
答案 1 :(得分:9)
显然这是个人的事情,但我不会删除错误消息。
如果我要使用简单的解决方案,那么我将删除[Required]属性并向控制器添加验证代码,以便在缺少日期时添加错误,或者如果它是正确的类型则将其设置为备用值。
如果我想采用更复杂的解决方案,我会将验证放在模型级别。可能是模型必须实现的基类或接口。 ValidationHelper类,带有静态Validate(IValidate对象)方法,该方法将检查ValidationAttributes并在Model上调用Validate方法。然后它将返回ValidationErrors的集合。然后编写一个定制的ModelBinder来理解模型验证并将它们映射到ModelState错误。