我们正在使用fluentvalidation(带有服务栈)来验证我们的请求DTO。我们最近扩展了我们的框架,以接受“ PATCH”请求,这意味着我们现在仅在补丁包含要验证的字段时才需要应用验证。
我们使用诸如此类的扩展方法来做到这一点:
RuleFor(dto => dto.FirstName).Length(1,30)).WhenFieldInPatch((MyRequest dto)=>dto.FirstName);
RuleFor(dto => dto.MiddleName).Length(1,30)).WhenFieldInPatch((MyRequest dto)=>dto.MiddleName);
RuleFor(dto => dto.LastName).Length(1,30)).WhenFieldInPatch((MyRequest dto)=>dto.LastName);
这意味着我们可以对POST / PUT或PATCH运行相同的验证。
我一直在寻找一种挂钩流利的验证框架的方法,例如,我们不需要在验证中的每行上复制.WhenFieldInPatch()规则,但尚未找到一种好的方法为此。
我尝试了以下操作:
我错过了什么吗?还是我在尝试不可能的事情?
谢谢
答案 0 :(得分:2)
当我需要共享Fluent验证逻辑时,我会使用扩展方法,下面是shared Extension methods for TechStacks的示例,例如:
public static class ValidatorUtils
{
public static bool IsValidUrl(string arg) => Uri.TryCreate(arg, UriKind.Absolute, out _);
public static string InvalidUrlMessage = "Invalid URL";
public static IRuleBuilderOptions<T, string> OptionalUrl<T>(
this IRuleBuilderInitial<T, string> propertyRule)
{
return propertyRule
.Length(0, UrlMaxLength)
.Must(IsValidUrl)
.When(x => !string.IsNullOrEmpty(x as string))
.WithMessage(InvalidUrlMessage);
}
}
以及some examples的共享位置:
public class CreatePostValidator : AbstractValidator<CreatePost>
{
public CreatePostValidator()
{
RuleSet(ApplyTo.Post, () =>
{
RuleFor(x => x.Url).OptionalUrl();
});
}
}
public class UpdatePostValidator : AbstractValidator<UpdatePost>
{
public UpdatePostValidator()
{
RuleSet(ApplyTo.Put, () =>
{
RuleFor(x => x.Url).OptionalUrl();
});
}
}