我有一个带有Html.ValidationSummary(true)标记的Razor视图。
属性级别验证正常执行,并且错误地显示在字段旁边的消息。但是,对于通过实现IValidatable的Validate方法进行验证,我遇到了问题。
如果模型本身实现IValidatable,则将错误添加到模型状态并正确显示在Html.ValidationSummary(true)标记处(模型级别错误而不是属性级别) 但是,如果视图模型包含对复杂对象的引用(使用[Required] annotation修饰),则消息不会显示。它被添加到ModelState中,并且isValid正确地变为false。它位于错误列表中,并显示为模型级别错误但不显示。 (如果使用Html.ValidationSummary(false),则显示消息)。
这是不可行的吗?难道我做错了什么?辩论转向Fluent,但这又是更多的工作......
以下是代码示例: 查看型号:
public class ViewModel
{
[Required]
public TestModel DataModel { get; set; }
}
TestModel:
public class TestModel : IValidatableObject
{
[Display(ResourceType = typeof(ViewResources), Name = "Field1")]
public string Field1 { get; set; }
public string Field2 { get; set; }
[Required]
public string Field3 { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (string.IsNullOrEmpty(Field1) && string.IsNullOrEmpty(Field2))
{
yield return new ValidationResult("Need to enter either Field1 or Field2.");
}
}
}
Razor查看:
@using (Ajax.BeginForm(new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "createDialog" }))
{
@Html.ValidationSummary(true)
<fieldset>
<div class="editor-label">
@Html.LabelFor(model => model.DataModel.Field1)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.DataModel.Field1)
@Html.ValidationMessageFor(model => model.DataModel.Field1)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.DataModel.Field2)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.DataModel.Field2)
@Html.ValidationMessageFor(model => model.DataModel.Field2)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.DataModel.Field3)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.DataModel.Field3)
@Html.ValidationMessageFor(model => model.DataModel.Field3)
</div>
<p>
<input type="submit" value="Submit"/>
</p>
</fieldset>
控制器:
if (!ModelState.IsValid) return View();
return View();
答案 0 :(得分:0)
不是一个干净的实现,但你仍然可以使用它。
if (!ModelState.IsValid)
{
System.Web.Mvc.ModelState modelStateObj = new ModelState();
bool isModelStateAvailable = ModelState.TryGetValue("DataModel", out modelStateObj);
if (isModelStateAvailable)
{
ModelState.Remove("DataModel");
modelStateObj.Errors.ToList().ForEach(t => { ModelState.AddModelError(string.Empty, t.ErrorMessage); });
}
}