客户端验证(表示层中的验证)

Even when the source of truth is the domain model and ultimately you must have validation at the domain model level, validation can still be handled at both the domain model level (server side) and the UI (client side).

即使领域模型是事实的唯一来源,并且最终你必须在领域模型层进行验证,但验证工作依然可以同时由领域模型层(服务端)和 UI 界面(客户端)来共同承担。

Client-side validation is a great convenience for users. It saves time they would otherwise spend waiting for a round trip to the server that might return validation errors. In business terms, even a few fractions of seconds multiplied hundreds of times each day adds up to a lot of time, expense, and frustration. Straightforward and immediate validation enables users to work more efficiently and produce better quality input and output.

客户端验证为用户提供了极大的便利。它帮用户省去了等待服务器往返请求并返回验证错误的时间。从业务角度来看,哪怕每天只有几百次操作,每次节省几分之一秒,累积起来也是一笔可观的时间、成本和挫败感的节省。简单直接的即时验证能让用户的工作更高效,并产出更高质量的输入和输出。

Just as the view model and the domain model are different, view model validation and domain model validation might be similar but serve a different purpose. If you are concerned about DRY (the Don't Repeat Yourself principle), consider that in this case code reuse might also mean coupling, and in enterprise applications it is more important not to couple the server side to the client side than to follow the DRY principle.

正如视图模型(ViewModel)和领域模型不同一样,视图模型的验证与领域模型的验证可能看起来很相似,但它们服务的目的是截然不同的。如果你在意 DRY(不要重复自己)原则,需要考虑到在这种情况下,代码复用可能也意味着耦合。而在企业级应用中,避免将服务端与客户端耦合在一起,比死守 DRY 原则要重要得多。

Even when using client-side validation, you should always validate your commands or input DTOs in server code, because the server APIs are a possible attack vector. Usually, doing both is your best bet because if you have a client application, from a UX perspective, it is best to be proactive and not allow the user to enter invalid information.

即使使用了客户端验证,你也应该始终在服务端代码中验证你的命令(Commands)或输入的数据传输对象(DTOs),因为服务器 API 是潜在的攻击入口。通常来说,双管齐下是最好的策略,因为如果你有一个客户端应用,从用户体验(UX)的角度来看,采取主动措施、不让用户输入无效信息是最好的。

Therefore, in client-side code you typically validate the ViewModels. You could also validate the client output DTOs or commands before you send them to the services.

因此,在客户端代码中,你通常会去验证视图模型(ViewModels)。你也可以在将客户端输出的 DTOs 或命令发送给服务之前对它们进行验证。

The implementation of client-side validation depends on what kind of client application you are building. It will be different if you're validating data in an MVC web application with most of the code in .NET versus a SPA web application with the validation code in JavaScript or TypeScript.

至于客户端验证的具体实现方式,则取决于你正在构建哪种类型的客户端应用。如果是在大部分代码使用 .NET 的 MVC Web 应用中进行数据验证,与在使用 JavaScript 或 TypeScript 编写验证代码的 SPA(单页应用)中进行验证,做法会有很大的不同。

In summary, these are the most important concepts in regards to validation:

总之,关于验证,以下是几个最核心的概念:

  • Entities and aggregates should enforce their own consistency and be "always valid". Aggregate roots are responsible for multi-entity consistency within the same aggregate.

    实体和聚合应该强制维护自身的一致性,并且必须“始终保持有效”。聚合根负责维护同一个聚合内部多个实体之间的一致性。

  • If you think that an entity needs to enter an invalid state, consider using a different object model—for example, using a temporary DTO until you create the final domain entity.

    如果你觉得某个实体需要进入一种“无效状态”,可以考虑换一种对象模型——比如,在最终创建领域实体之前,先使用一个临时的数据传输对象(DTO)来过渡。

  • If you need to create several related objects, such as an aggregate, and they are only valid once all of them have been created, consider using the Factory pattern.

    如果你需要创建多个相互关联的对象(例如一个聚合),并且只有在它们全部创建完毕后才算有效,可以考虑使用工厂模式(Factory pattern)。

  • In most of the cases, having redundant validation in the client side is good, because the application can be proactive.

    在大多数情况下,在客户端进行冗余的验证是一件好事,因为这能让应用程序表现得更加积极主动。

posted @ 2026-05-17 19:09  菜鸟吊思  阅读(7)  评论(0)    收藏  举报