【发布时间】:2011-04-12 20:20:21
【问题描述】:
这对我来说没有任何意义。
看看这个 ViewModel:
public class SelectService
{
[Required]
public int? SelectedServiceId { get; set; }
}
看看这个动作:
[HttpPost]
public virtual ActionResult SelectService()
{
TryUpdateModel(WizardContainer.SelectService, "SelectService");
TryValidateModel(WizardContainer.SelectService, "SelectService"); // if I remove this, ModelState.IsValid will always be true
if (ModelState.IsValid)
{
return RedirectToAction("OtherAction");
}
else
{
return View(WizardContainer);
}
}
现在阅读 S. Sanderson 的 Apress ASP.NET MVC 2 Framework 节选:
每当您使用模型绑定来填充模型对象时 - 通过将其作为操作方法接收 参数,或者通过手动调用 UpdateModel() 或 TryUpdateModel() - 然后 DefaultModelBinder 将 自动运行与它已更新的所有模型对象关联的验证器(即,它在 已在至少一个属性上设置了值)。 如果您以任何其他方式更新模型对象,除非您明确告知,否则不会运行其验证器 运行它们的框架。
那么,为什么当我调用 TryUpdateModel() 时从未发生验证?要进行验证,我必须使用 TryValidateModel() 显式验证。
更新
这是在同一个控制器中按预期工作的非常相似的操作:
[HttpPost]
public virtual ActionResult Index(string nextButton)
{
TryUpdateModel(WizardContainer.Index);
if (nextButton != null && ModelState.IsValid)
{
return RedirectToAction("OtherAction");
}
else
{
return View(WizardContainer.Index);
}
}
这是 ViewModel:
public class Index
{
[Required]
public DateTime? SelectedServiceTime { get; set; }
}
更新 2
我改变了一些东西,现在它的行为符合预期,但我仍然不明白为什么。
查看编辑后的动作:
[HttpPost]
public virtual ActionResult SelectService()
{
TryUpdateModel(WizardContainer.SelectService);
//TryValidateModel(WizardContainer.SelectService, "SelectService"); // not needed anymore
if (ModelState.IsValid)
{
return RedirectToAction("OtherMethod");
}
else
{
return View(WizardContainer.SelectService);
}
}
现在的区别只是我传递给 TryUpdateModel() 的对象是我传递给视图的对象,而不是我传递给视图的对象的属性。什么交易哟?
【问题讨论】:
-
如果使用 int 而不是可为空的 int 会发生什么?您将可空参数标记为必需的,这对于 Web 请求没有意义,因为可空意味着根本没有提供任何值(请求中不包含参数)。允许空值但将属性标记为Required 会产生冲突的验证逻辑。
-
@Nathan - 您不能要求值类型。它总是有价值的。您应该使用可为空的 int。
-
@Bigglesby 好的,我没有考虑到这一点。好点子。
-
您是否设置了一个不会自动执行验证的自定义模型绑定器?
-
@Adrian - 没有机会。我没有注册任何其他模型绑定器,也没有装饰任何自定义模型以使用任何其他绑定器。
标签: c# .net asp.net-mvc asp.net-mvc-2