【发布时间】:2022-01-21 05:35:57
【问题描述】:
对于我的 .Net 5 workerservice 应用,我想通过实现 IValidateOptions 接口来验证选项,但不想编写自己的错误消息。这就是我想使用 FluentValidation.AspNetCore 包的原因。
给定模型
namespace App.Models
{
public class MyOptions
{
public string Text { get; set; }
}
}
我添加了验证规则
namespace App.ModelValidators
{
public class MyOptionsValidator : AbstractValidator<MyOptions>
{
public MyOptionsValidator()
{
RuleFor(model => model.Text).NotEmpty();
}
}
}
接下来我在验证中使用这个验证器
namespace App.OptionsValidators
{
public class MyOptionsValidator : IValidateOptions<MyOptions>
{
private readonly IValidator<MyOptions> _validator;
public MyOptionsValidator(IValidator<MyOptions> validator)
{
_validator = validator;
}
public ValidateOptionsResult Validate(string name, MyOptions options)
{
var validationResult = _validator.Validate(options);
if (validationResult.IsValid)
{
return ValidateOptionsResult.Success;
}
return ValidateOptionsResult.Fail(validationResult.Errors.Select(validationFailure => validationFailure.ErrorMessage));
}
}
}
最后我设置了 DI 容器
services.AddTransient<IValidator<MyOptions>, ModelValidators.MyOptionsValidator>();
services.AddSingleton<IValidateOptions<MyOptions>, OptionsValidators.MyOptionsValidator>();
services.Configure<MyOptions>(configuration.GetSection("My"));
我想知道这是否可以简化?
也许我可以只实现IValidateOptions 接口,避免AbstractValidator 并在.Validate() 方法中编写流畅的规则?
我想要实现的示例代码
namespace App.OptionsValidators
{
public class MyOptionsValidator : IValidateOptions<MyOptions>
{
public ValidateOptionsResult Validate(string name, MyOptions options)
{
var validationResult = options.Text.Should.Not.Be.Empty();
if (validationResult.IsValid)
{
return ValidateOptionsResult.Success;
}
return ValidateOptionsResult.Fail(validationResult.ErrorMessage);
}
}
}
所以我不再需要AbstractValidator<MyOptions>。
我不确定我的第一种方法
我没有使用 FluentValidation,而是使用 DataAnnotations。
- 我将
[Required]属性添加到Text属性中 - 我完全删除了课程
MyOptionsValidator : AbstractValidator<MyOptions> - 我只在 DI 设置中注册这个
.
services.AddSingleton<IValidateOptions<MyOptions>, OptionsValidators.MyOptionsValidator>();
services.Configure<MyOptions>(configuration.GetSection("My"));
在MyOptionsValidator 内部,我像这样验证选项
public ValidateOptionsResult Validate(string name, MyOptions options)
{
var validationResults = new List<ValidationResult>();
if (!Validator.TryValidateObject(options, new ValidationContext(options), validationResults, true))
{
return ValidateOptionsResult.Fail(validationResults.Select(validationResult => validationResult.ErrorMessage));
}
return ValidateOptionsResult.Success;
}
但也许还有更好的方法:)
【问题讨论】:
-
当然可以,但是会破坏目的:“不想写我自己的错误信息”,不仅仅是信息,整个验证
-
@Eldar 请问您将如何解决这个问题?
-
我会坚持你当前的实现。删除验证器会给您带来验证模型和创建验证结果的负担。
-
@Eldar 你觉得我的方法怎么样?这将消除一些东西
-
我仍然采用第一种方法。您删除了一个验证器,而现在您正在使用另一个框架进行验证。随着应用程序变得越来越复杂,使用 2 个验证框架可能会变得很麻烦。
标签: c# .net .net-core .net-5 fluentvalidation