自定义模型绑定后验证视图模型

Pau*_*ann 2 validation custom-model-binder asp.net-mvc-3

我有一个实现的视图模型IValidatableObject包含一个字符串和另一个视图模型的集合,如下所示:

public sealed class MainViewModel
{
    public string Name { get; set; }
    public ICollection<OtherViewModel> Others { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我的验证Others使用以下提供的合同检查每个对象与不同的规则IValidatableObject:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    foreach (var other in this.Others)
    {
        // validate or yield return new ValidationResult
    }
}
Run Code Online (Sandbox Code Playgroud)

由于真实的复杂结构,MainViewModel我不得不创建一个自定义模型绑定器,它重新构建模型并将POST数据分配给相关组件.我得到的问题是没有任何东西得到验证,导致上下文级别的验证错误,因为它违反了某些数据库约束,我不确定我做错了什么 - 我以为我ModelState.IsValid会Validate在我的视图上调用该方法模型,但它似乎没有那样下去.

我的模型绑定器看起来像这样:

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    int modelId = (int)controllerContext.RouteData.Values["id"];

    // query the database and re-build the components of the view model

    // iterate the POST data and assign to the model where necessary

    // should I be calling something here to validate the model before it's passed to the controller?

    return model;
}
Run Code Online (Sandbox Code Playgroud)

任何帮助赞赏!

Validator.TryValidateObject

好吧,似乎我离我更近一点了.我现在可以IValidatableObject通过将以下内容添加到我的自定义模型绑定器来运行我的方法:

var validationResults = new HashSet<ValidationResult>();
var isValid = Validator.TryValidateObject(model, new ValidationContext(model, null, null), validationResults, true);
Run Code Online (Sandbox Code Playgroud)

似乎Validator.TryValidateObject调用验证方法并设置最后一个参数以true使其验证所有属性.但是,我现在validationResults仍然坚持使用控制器,以便以有意义的方式使用它们.

Pau*_*ann 10

我应该已经意识到我可以使用ModelState.AddModelError通过自定义绑定器,我已经设法通过在将模型返回到控制器之前将以下内容添加到我的自定义模型绑定器中来正常工作:

var validationResults = new HashSet<ValidationResult>();
var isValid = Validator.TryValidateObject(model, new ValidationContext(model, null, null), validationResults, true);
if (!isValid)
{
    foreach (var result in validationResults)
    {
        bindingContext.ModelState.AddModelError("", result.ErrorMessage);
    }
}

return model;
Run Code Online (Sandbox Code Playgroud)

现在,这会向我的页面返回所有错误的列表,现在返回ModelState.IsValid对我的控制器操作的检查false.

  • @Rajpurohit您将上面的代码放在自定义模型绑定器类中. (2认同)