【问题标题】:How to validate input data if there are CQRS, DTO and Entity?如果有 CQRS、DTO 和实体,如何验证输入数据?
【发布时间】:2020-02-23 17:00:27
【问题描述】:

.Net Core 3,简洁架构。

我已经阅读了很多关于使用 CQRS 进行数据验证的文章。例如therethere

我做了一些结论:

  1. 需要验证 DTO 中的数据。这是实体的合同。
  2. 作者的一些建议将日期验证到实体(域)中。
  3. 在 CQRS AbstractValidator 中,我们也可以验证,但其他规则。

电子邮件字段验证将在 1 和 2 中进行。 年龄限制将在3.

但是服务器中的三个验证 + 客户端中的一个验证是有问题的(大 DRY)。 DTO 或实体中哪里有更好的验证?我认为在 DTO 中,因为当我从输入中获取 DTO 时,我可以验证并调用 ModelState.IsValid。但我也阅读了一些需要验证实体中的输入数据的文章。

所以,我很困惑。你能解释一下吗:

如果需要验证电子邮件字段和年龄限制 (18),需要在 CQRS 的 Clean Architecture 中进行验证吗?

【问题讨论】:

    标签: asp.net-core domain-driven-design cqrs clean-architecture


    【解决方案1】:

    您所有的 Api 合同、命令都应该依赖于原始类型。一旦你想初始化你的域模型,如果 smth 是错误的,这里就是你无法做到的地方。如果你做 DDD,它建议防止对象处于无效状态而不是验证无效对象(域模型与基于 Crud)。

    【讨论】:

    • 我想做 DDD。我应该为用户输入验证 DTO(或 ViewModel),并验证域中的命令对象,不是吗?我还没抓到。
    • 不,你不应该。如果您的命令或 dto 依赖于原始类型(int、string、bool)。您需要创建另一个类(验证器)来验证它。这意味着您将复制您的域逻辑。因为只有 domain 知道 Address 只有在提供 Country 时才有效,所以 var address = new Address(country, bla, bla) 在提供 null country 时会失败。
    • 有时,如果数据存在,开发人员会预先验证命令和 dto。但不违反您的域规则。所以在你的命令中你可以检查国家是否为空,这不是一个有效的命令,但没有更多
    【解决方案2】:

    清洁架构按层划分职责,每一层都应该有自己的验证逻辑。

    每一层都应该拒绝违反其层职责的输入。这是验证。因此,验证的含义根据其上下文而有所不同。

    【讨论】:

      【解决方案3】:

      这完全取决于验证的类型。是表面验证还是深度验证?

      表面验证是指密码强度或检查 URL 或电子邮件地址的正确格式。而深度验证是对领域很重要的事情。所以这可能是这样的,这种货物是危险的还是这个人的风险太大而无法提供信贷。

      查看这篇从 CQRS 角度更详细地解释该概念的帖子:How to validate Commands in a CQRS Application

      【讨论】:

        猜你喜欢
        • 2013-12-04
        • 2020-09-25
        • 2020-11-23
        • 1970-01-01
        • 2019-06-07
        • 2020-08-06
        • 1970-01-01
        • 2021-06-16
        • 1970-01-01
        相关资源
        最近更新 更多