我已经在我的模型上验证了我的IErrorDataInfo实现,但我似乎无法从我的模型上的IErrorDataInfo获取验证错误到我的控制器中的ASP.MVC ModelState。这样做的最佳方式是什么?
我可以遍历我的结果并手动将它们添加到ModelState中,但必须有一种更简单的方法。
这是我的客户控制器。
[HttpPost]
public ActionResult Edit(Grade grade)
{
MvcApplication.Container.BuildUp(grade);
if (!ModelState.IsValid)
{
return View("Edit", grade);
}
try
{
var provider = MvcApplication.Container.Resolve<IGradeProvider>();
provider.Edit(grade);
return RedirectToAction("Details", "Grade", new { id = grade.GradeId });
}
catch
{
return RedirectToAction("Index");
}
}
这是我的IErrorDataInfo implimentation
public abstract class AbstractBase : IAbstractBase
{
#region IDataErrorInfo
public abstract ValidationResult SelfValidate();
public bool IsValid
{
get
{
return SelfValidate().IsValid;
}
}
public string Error
{
get
{
var results = SelfValidate().Errors.Select(s => string.Format("● {0}{1}", s.ErrorMessage, Environment.NewLine)).ToArray();
return string.Join("", results);
}
}
public string this[string columnName]
{
get
{
var validationResults = SelfValidate();
if (validationResults == null) return string.Empty;
var columnResults = validationResults.Errors.FirstOrDefault(x => string.Compare(x.PropertyName, columnName, true) == 0);
return columnResults != null ? columnResults.ErrorMessage : string.Empty;
}
}
#endregion
}
更新:
我应该补充说我正在使用依赖注入。问题不在于IErrorDataInfo不能与ASP.MVC 3一起使用,问题是IErrorDataInfo需要注入的参数才能正常工作。为了解决这个问题,我在构建对象之后但在调用ModelState.IsValid之前手动调用了TryValidateModel。
答案 0 :(得分:0)
DataErrorInfoModelValidatorProvider正在使用IDataErrorInfo的Item成员来收集属性级别验证错误,并使用Error属性进行模型级别验证错误:
public string Error
{
//This is needed for model level validation to work
get { throw new NotImplementedException(); }
}
public string this[string propertyName]
{
//This is needed for property level validation to work
get { throw new NotImplementedException(); }
}
正确实现后,这一切都应该是开箱即用的(如果你没有禁用DataErrorInfoModelValidatorProvider)。
更新:
如果您的模型在模型绑定过程中尚未准备好进行验证(或者您不希望它由ASP.NET MVC绑定),则需要在调用ModelState.IsValid方法之前手动验证模型。您的控制器可能如下所示:
[HttpPost]
public ActionResult Edit(Grade grade)
{
MvcApplication.Container.BuildUp(grade);
//Add this to your controller.
TryValidateModel(grade);
if (!ModelState.IsValid)
{
return View("Edit", grade);
}
try
{
var provider = MvcApplication.Container.Resolve<IGradeProvider>();
provider.Edit(grade);
return RedirectToAction("Details", "Grade", new { id = grade.GradeId });
}
catch
{
return RedirectToAction("Index");
}
}