如何让C#IErrorDataInfo与ASP.MVC 3一起使用

时间:2011-12-13 15:13:49

标签: c# asp.net-mvc asp.net-mvc-3

我已经在我的模型上验证了我的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。

1 个答案:

答案 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");
  }
}