c# - 如何避免 FluentValidation 中的重复外部调用
问题描述
我正在为一个需要许多类似/相同的数据库调用的类(例如 Car)编写验证。
RuleFor(c => c.Id).MustAsync(async (car, id, context, cancellation) =>
{
return await _carRepository.Get(id) != null;
}).WithMessage("Car with id '{PropertyValue}' does not exist!");
RuleFor(c => c.Model).MustAsync(async (car, model, context, cancellation) =>
{
var expectedModel = (ModelType)context.ParentContext.RootContextdata["ExpectedModel"]
var databaseCar = await _carRepository.Get(car.Id); // Repeated database call
return databaseCar.Model == expectedModel;
}).WithMessage('Stored car does not have the expected model.');
理想情况下,我会执行一次此调用,但不建议将结果存储为验证器实例上的成员,并且ValidateAsync
使用添加到上下文中的数据库结果覆盖(类似于ExpectedModel
上面的示例)会导致检索它的代码相当笨拙.
我错过了什么吗?
解决方案
一种快速的解决方案可能是在您的 Repository 类上添加某种记忆/缓存,以便在同一上下文中对同一 Car 的多个请求(例如 HTTP 请求)将记住并返回同一对象,而无需多次往返。但可能有更好的方法。
有不同级别的验证需要考虑。正如 Jammer 所指出的,FluentValidation 通常用于验证给定模型的一致性:客户端是否向我发送了表面上看起来是有效请求的东西?在给定当前数据状态的情况下确定该请求是否有效是人们经常以不同方式进行的另一个级别的验证。
您可以两全其美的一种方法是创建一个新类来表示给定的汽车模型以及应用程序验证它所需的一切。
public class ValidCar
{
public CarModel Model {get; set;}
public CarEntity Entity {get; set;}
}
首先,您将所需的所有数据组装到一个new ValidCar
中,然后您可以在这个新模型上使用 FluentValidation 规则来确保它实际上是有效的。
这种方法的一个好处是您可以让您的业务逻辑方法需要 aValidCar
作为参数,而不仅仅是 a CarModel
。这使得意外忘记在某些代码路径中验证汽车变得非常困难,并且它预先打包了可能对您计划使用的大部分业务级逻辑有用的数据。
推荐阅读
- r - 如何在 ggplot 2 中获取这些代码的图例,R
- javascript - 带有 void 的 return 语句能实现什么?
- python - 如果我在 1080 x 1440 处捕获 Python,有没有办法只从每 10 个像素读取像素值
- r - 无法将 RSelenium 连接到 Selenium 服务器:“已超时”
- swift - 如何在 Swift 中为 Dictionary 制作自定义扩展?
- python - 如何在 viscode 的交互窗口中查看由希腊字母表示的变量?
- webgl - WebGL 用 gl.TRIANGLES 得到了奇怪的绘图(循环未关闭)
- sql - 是否可以直接在我的 ASP.NET WEB API 应用程序中使用我的 SQL 内部联接查询,或者翻译更好,如果可以,怎么做?
- python - 在python中结合mp4和wav
- vue.js - 使用时刻 vuejs 格式化日期