类 层次结构的 C# FluentValidation
C# FluentValidation for a hierarchy of classes
我有一个数据层次结构 classes
public class Base
{
// Fields to be validated
}
public class Derived1 : Base
{
// More fields to be validated
}
public class Derived2 : Base
{
// More fields to be validated
}
在不复制 Base class 字段规则的情况下,使用 FluentValidation 框架验证 Derived1 和 Derived2 的合适方法是什么?
一种方法如下:
public class Base
{
public string BaseName { get; set; }
}
public class Derived1 : Base
{
public string Derived1Name { get; set; }
}
public class BaseValidator<T> : AbstractValidator<T> where T : Base
{
public BaseValidator()
{
RuleFor(b => b.BaseName).NotNull();
}
}
public class Derived1Validator : BaseValidator<Derived1>
{
public Derived1Validator()
{
RuleFor(d => d.Derived1Name).NotNull();
}
}
所以你首先创建你的基础验证器,让它接受一个泛型类型参数并指定泛型类型必须是 base
类型。为您的基地设置一般规则 class 并继续前进。
对于验证基础 class 的 children 的任何验证器,这些验证器继承自 baseValidator,其中 T 将是您的派生 class 类型。
public class Derived2Validator : AbstractValidator<Derived2>
{
public Derived2Validator()
{
Include(new BaseValidator());
Include(new Derived1Validator());
RuleFor(d => d.Derived1Name).NotNull();
}
}
Derived2Validator
不需要继承BaseValidator
或Derived1Validator
.
使用 Include
方法来包含来自其他验证器的规则。
我尝试了 Include() 方法,但这并没有给我想要的结果,因为 .net core 中 swagger 生成的模型没有显示任何变化。起作用的是创建一个新的 class 以继承具有基础 class
的验证器
/// <summary>
/// Base Class for entity validator classes that specifies a base validator class
/// </summary>
/// <typeparam name="T">The Type being validated</typeparam>
/// <typeparam name="TBaseClass">The validater assigned to the base type of the type being validated</typeparam>
public abstract class BaseAbstractValidator<T, TBaseClass> : AbstractValidator<T>
where TBaseClass : IEnumerable<IValidationRule>
{
protected BaseAbstractValidator() => AppendRules<TBaseClass>();
/// <summary>
/// Add the set of validation rules
/// </summary>
/// <typeparam name="TValidationRule"></typeparam>
private void AppendRules<TValidationRule>() where TValidationRule : IEnumerable<IValidationRule>
{
var rules = (IEnumerable<IValidationRule>)Activator.CreateInstance<TValidationRule>();
foreach (var rule in rules)
{
AddRule(rule);
}
}
}
我有一个数据层次结构 classes
public class Base
{
// Fields to be validated
}
public class Derived1 : Base
{
// More fields to be validated
}
public class Derived2 : Base
{
// More fields to be validated
}
在不复制 Base class 字段规则的情况下,使用 FluentValidation 框架验证 Derived1 和 Derived2 的合适方法是什么?
一种方法如下:
public class Base
{
public string BaseName { get; set; }
}
public class Derived1 : Base
{
public string Derived1Name { get; set; }
}
public class BaseValidator<T> : AbstractValidator<T> where T : Base
{
public BaseValidator()
{
RuleFor(b => b.BaseName).NotNull();
}
}
public class Derived1Validator : BaseValidator<Derived1>
{
public Derived1Validator()
{
RuleFor(d => d.Derived1Name).NotNull();
}
}
所以你首先创建你的基础验证器,让它接受一个泛型类型参数并指定泛型类型必须是 base
类型。为您的基地设置一般规则 class 并继续前进。
对于验证基础 class 的 children 的任何验证器,这些验证器继承自 baseValidator,其中 T 将是您的派生 class 类型。
public class Derived2Validator : AbstractValidator<Derived2>
{
public Derived2Validator()
{
Include(new BaseValidator());
Include(new Derived1Validator());
RuleFor(d => d.Derived1Name).NotNull();
}
}
Derived2Validator
不需要继承BaseValidator
或Derived1Validator
.
使用 Include
方法来包含来自其他验证器的规则。
我尝试了 Include() 方法,但这并没有给我想要的结果,因为 .net core 中 swagger 生成的模型没有显示任何变化。起作用的是创建一个新的 class 以继承具有基础 class
的验证器/// <summary>
/// Base Class for entity validator classes that specifies a base validator class
/// </summary>
/// <typeparam name="T">The Type being validated</typeparam>
/// <typeparam name="TBaseClass">The validater assigned to the base type of the type being validated</typeparam>
public abstract class BaseAbstractValidator<T, TBaseClass> : AbstractValidator<T>
where TBaseClass : IEnumerable<IValidationRule>
{
protected BaseAbstractValidator() => AppendRules<TBaseClass>();
/// <summary>
/// Add the set of validation rules
/// </summary>
/// <typeparam name="TValidationRule"></typeparam>
private void AppendRules<TValidationRule>() where TValidationRule : IEnumerable<IValidationRule>
{
var rules = (IEnumerable<IValidationRule>)Activator.CreateInstance<TValidationRule>();
foreach (var rule in rules)
{
AddRule(rule);
}
}
}