假设您有一个类似的课程:
public enum Kind { Kind1, Kind2 }
public class MyForm
{
public string Kind { get; set; }
public ACustomClass1 Custom1 { get; set; }
public ACustomClass2 Custom2 { get; set; }
}
你想验证Custom1
用Custom1Validator
时Kind == Kind1
(和Custom2
用Custom2Validator
时Kind == Kind2
,很明显)
继续进行版本8.6.0的最佳方法是什么?
此刻,我已经完成了这样的工作(但我觉得很尴尬):
public class MyFormValidator : AbstractValidator<MyForm>
{
public MyFormValidator (IStringLocalizer<Strings> localizer, Custom1Validator validator1, Custom2Validator validator2)
{
//validate Kind and then, in function of Kind, use correct validator
RuleFor(x => x).Custom((f, context) => {
if (!Enum.TryParse<Kind>(f.Kind, out var kind))
{
context.AddFailure(localizer["Invalid Kind"]);
return;
}
switch (kind)
{
case Kind.Kind1:
if (f.Custom1 == null)
{
context.AddFailure(localizer["Invalid Kind"]);
}
else if (! validator1.Validate(f.Custom1, out var firstError))
{
context.AddFailure(firstError);
}
break;
case Kind.Kind2:
if (f.Custom2 == null)
{
context.AddFailure(localizer["Invalid Kind"]);
}
else if (!validator2.Validate(f.Custom2, out var firstError))
{
context.AddFailure(firstError);
}
break;
}
});
}
}
请注意,我使用的是带有依赖项注入的asp.net核心(这就是为什么存在这种情况,IStringLocalizer
而我不能SetValidator
用于Custom1和Custom2)
相反,我想要的是
RuleFor(x => x.Kind).NotEmpty().IsEnumName(typeof(Kind)).withMessage(_ => localizer["Invalid Kind"]);
RuleFor(x => x.Custom1).NotEmptyWhen(f => f.Kind == Kind.Custom1.ToString()).withMessage(_ => localizer["Invalid Kind"])
RuleFor(x => x.Custom1).SetValidator(validator1); //would be executed only when custom1 is not null
//与custom2相同
问题是我看不到该NotEmptyWhen
方法的编码方法
重组?
通过您发布的代码片段的外观上来看,我相信这MyForm
将永远不会有一个人口稠密Custom1
并且Custom2
在同一个请求属性。因此,我建议您不要直接使用表示要验证的有效负载的模型,而不要拥有同时包含两种有效负载类型的父模型。这样一来,您就不会在需要的地方遇到这种讨厌的检查类型。
您的一个表单端点接受Custom1
一个与关联的Custom1Validator
。表单端点中的另一个端点接受Custom2
带有关联的Custom2Validator
。它们是分离的。您可以安全地更改一个而不影响另一个。
使用流利的验证条件(何时/除非)
如果您沉迷于让一个模型负责代表多个请求的有效负载(请不要这么做),则可以使用When()
库提供的方法。看看他们关于条件规则的文档。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句