自定义模型绑定后验证视图模型 [英] Validating a view model after custom model binding

查看:109
本文介绍了自定义模型绑定后验证视图模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a view model that implements IValidatableObject that contains a string and a collection of another view model, something like this:

public sealed class MainViewModel
{
    public string Name { get; set; }
    public ICollection<OtherViewModel> Others { get; set; }
}

我的验证会检查 其他中的每个对象使用 IValidatableObject 提供的合同针对不同的规则:

My validation checks each object in Others against different rules using the contract provided by IValidatableObject:

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

由于实际的 MainViewModel 我必须创建一个自定义模型活页夹,该活页夹可以重新构建模型并将POST数据分配给相关组件。我得到的问题是,没有任何事情得到验证,这导致上下文级别的验证错误,因为它违反了某些数据库约束,而且我不确定自己在做什么错-我假设 ModelState .IsValid 会在我的视图模型上调用 Validate 方法,但似乎并没有那么简单。

Because of the complex structure of the real MainViewModel I have had to create a custom model binder which re-builds the model and assigns POST data to the relevant components. The problem that I'm getting is that nothing is getting validated resulting in validation errors at the context level as it violates certain database constraints and I'm not sure what I'm doing wrong - I assumed that ModelState.IsValid would invoke the Validate method on my view model but it doesn't seem to go down that way.

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

My model binder looks like this:

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;
}

任何帮助表示赞赏!

Validator.TryValidateObject

好的,看来我离我们有点近了。现在,可以通过将以下内容添加到自定义模型绑定程序中来运行 IValidatableObject 方法:

OK, seems I'm a little closer. I can now get my IValidatableObject method to run by adding the following to my custom model binder:

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

似乎 Validator.TryValidateObject 调用了验证方法并将最后一个参数设置为 true 会使它验证所有属性。但是,我现在坚持将 validationResults 传递给控制器​​,以便可以有意义的方式使用它们。

Seems that Validator.TryValidateObject invokes the validation method and setting the last parameter to true causes it to validate all properties. However, I'm now stuck with getting the validationResults to the controller so they can be used in a meaningful way.

推荐答案

我应该已经意识到我可以通过自定义绑定器使用 ModelState.AddModelError ,我已经设法使它正常工作现在,通过将以下内容添加到我的自定义模型绑定程序中,然后将模型返回到控制器,可以正确地进行以下操作:

I should have realised that I could use the ModelState.AddModelError through a custom binder, I've managed to get this working correctly now by adding the following to my custom model binder before returning the model to the controller:

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;

这现在将所有错误的列表返回到我的页面和 ModelState。 IsValid 检查我的控制器操作现在返回 false

This now returns a list of all errors to my page and the ModelState.IsValid check on my controller action is now returning false.

这篇关于自定义模型绑定后验证视图模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆