验证嵌套的ViewModels [英] Validation of nested ViewModels

查看:65
本文介绍了验证嵌套的ViewModels的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个ViewModel(简化版):

I have two ViewModels (simplified):

public class ParentViewModel
{
    public ParentViewModel
    {
        Content = new ChildViewModel();
    }

    public ChildViewModel Content { get; set, }
}

public class ChildViewModel
{
    [Required]
    public string Name1 { get; set, }
    [Required]
    public string Name2 { get; set, }
}

以及以下控制器的后续操作:

And the following controller post action:

[HttpPost]
public ActionResult Create(ParentViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        // process viewModel -> write something into database
        return RedirectToAction("Index");
    }
    return View(viewModel);
}

现在,我将以下请求中的表单值发送到与该操作相对应的URL(通常在Fiddler Request Builder中):

Now I am sending the following form values in a post request body to the URL corresponding to that action (manually in Fiddler Request Builder):

  • Content.Name1 = X

这很好用,在viewModel.Content中填充了Name1属性,Name2null,并且模型状态无效,因为需要Name2.因此,验证失败.

This works fine, the Name1 property is filled in viewModel.Content, Name2 is null and the model state is invalid because Name2 is required. So, validation fails as expected.

Xontent.Name1 = X Name1 = X 或其他任何东西,以使没有任何内容绑定到viewModel

Xontent.Name1=X or Name1=X or whatever so that nothing gets bound to the viewModel

现在viewModel.Content不是null(因为我在构造函数中实例化了它),但是所有属性Name1Name2都是null.这是预期的.我没有想到的是,模型状态是有效的,因此它通过了验证(由于存在不可为空的列,因此导致数据库异常).

Now viewModel.Content is not null (because I'm instantiating it in the constructor) but all properties Name1 and Name2 are null. This is expected. What I did not expect is that the model state is valid, so it passes the validation (leading to DB exceptions later because there are non-nullable columns).

如何改进此代码,以便在第二种情况下也可以进行验证?

How can I improve this code so that validation also works in the second case?

我做了三个实验:

  • 我在ParentViewModel构造函数中删除了Content的实例,然后在上面的第二个示例中,Contentnull,但是验证仍然通过.

  • I have removed the instantiation of Content in the ParentViewModel constructor, then Content is null in the second example above, but validation still passes.

我已经在Content属性中添加了[Required]属性(但没有在ParentViewModel构造函数中删除Content的实例化).这根本没有效果,上面两个测试的描述行为是相同的.

I have added a [Required] attribute to the Content property (but didn't remove the instantiation of Content in the ParentViewModel constructor). This has no effect at all, the described behaviour of the two tests above is the same.

我在Content属性中添加了[Required]属性,并且在ParentViewModel构造函数中删除了Content的实例化.这似乎像我想要的那样工作:在第二个测试中,Contentnull,并且由于[Required]属性而导致验证失败.看起来像这样:

I have added a [Required] attribute to the Content property and removed the instantiation of Content in the ParentViewModel constructor. This seems to work as I want: In the second test Content is null and validation fails due to the [Required] attribute. It would look like this:

public class ParentViewModel
{
    [Required]
    public ChildViewModel Content { get; set, }
}

public class ChildViewModel
{
    [Required]
    public string Name1 { get; set, }
    [Required]
    public string Name2 { get; set, }
}

我现在得出的结论是,在ParentViewModel构造函数中实例化Content子属性是问题的根源,并且模型绑定程序本身必须实例化子属性(或如果没有匹配的表单字段,则不能实例化).该请求),以使服务器端能够正常运行.

I would conclude now that instantiating the Content child property in the ParentViewModel constructor is the source of the problem and that the model binder itself must instantiate the child properties (or not, if there are no matching form fields in the request) in order to have a properly working server side validation.

我在其他几个视图模型构造函数中具有子属性实例化,并且直到现在都没有注意到此问题.那么,这通常是不好的做法吗?还有其他解决问题的方法吗?

I have child property instantiation in several other view model constructors and didn't notice this problem until now. So, is this generally a bad practice? Are there other ways to solve the problem?

推荐答案

第三个解决方案很好:

public class ParentViewModel
{
    [Required]
    public ChildViewModel Content { get; set, }
}

public class ChildViewModel
{
    [Required]
    public string Name1 { get; set, }
    [Required]
    public string Name2 { get; set, }
}

我现在在多个地方使用它,没有发现任何问题.

I'm using it now at several places and didn't notice any problems.

这篇关于验证嵌套的ViewModels的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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