C# FluentValidation如何创建公共零件
我有一个抽象(没关系)类: 和AddressCreateAPI类:C# FluentValidation如何创建公共零件,c#,fluentvalidation,C#,Fluentvalidation,我有一个抽象(没关系)类: 和AddressCreateAPI类: public class AddressCreateAPI { public string Street { get; set; } public string City { get; set; } public string ZipPostalCode { get; set; } public int StateProvinceId { get; set; } public string
public class AddressCreateAPI
{
public string Street { get; set; }
public string City { get; set; }
public string ZipPostalCode { get; set; }
public int StateProvinceId { get; set; }
public string ContactName { get; set; }
public string ContactPhone { get; set; }
public string ContactFaxNumber { get; set; }
public string ContactEmail { get; set; }
}
我的验证器:
public abstract class CarrierAbstractFluentValidation<T> : AbstractValidator<T> where T : CarrierAbstractFormAPI
{
public CarrierAbstractFluentValidation()
{
RuleFor(d => d.Name)
.NotEmpty().WithMessage("Name is required");
RuleFor(d => d.Fein)
.NotEmpty().WithMessage("Fein is required");
RuleFor(d => d.McNumber)
.NotEmpty().WithMessage("McNumber is required");
RuleFor(d => d.DotNumber)
.NotEmpty().WithMessage("DotNumber is required");
RuleFor(d => d.Address.Street)
.NotEmpty().WithMessage("Address Street is required");
RuleFor(d => d.Address.City)
.NotEmpty().WithMessage("Address City is required");
RuleFor(d => d.Address.StateProvinceId)
.InclusiveBetween(0, int.MaxValue).WithMessage("Address State is required");
}
}
财产。
我想移动一个部件:
RuleFor(d => d.Address.Street)
.NotEmpty().WithMessage("Address Street is required");
RuleFor(d => d.Address.City)
.NotEmpty().WithMessage("Address City is required");
RuleFor(d => d.Address.StateProvinceId)
.InclusiveBetween(0, int.MaxValue).WithMessage("Address State is required");
将它应用到每个my fluent验证器中,该验证器具有属性地址。如何执行?您可以使用以下扩展方法,通过反射检查传递的类型并应用指定的验证规则:
public static bool Apply<T, TProperty>(this AbstractValidator<T> validator, string propertyName, Action<IRuleBuilderInitial<T, TProperty>> rule)
{
var property = typeof(T).GetProperty(propertyName);
if (property == null)
{
Console.WriteLine($"{typeof(T).Name} does not expose property {propertyName}!");
return false;
}
if (!typeof(TProperty).IsAssignableFrom(property.PropertyType))
{
Console.WriteLine($"Property {typeof(T).Name}.{propertyName} is of type {property.PropertyType.Name} which is not (derived from) {typeof(TProperty).Name}!");
return false;
}
rule(validator.RuleFor(t => (TProperty)property.GetValue(t)));
return true;
}
公共静态bool Apply(此抽象验证器验证器、字符串属性名称、操作规则)
{
var property=typeof(T).GetProperty(propertyName);
if(属性==null)
{
WriteLine($“{typeof(T).Name}不公开属性{propertyName}!”);
返回false;
}
如果(!typeof(TProperty).IsAssignableFrom(property.PropertyType))
{
Console.WriteLine($“Property{typeof(T).Name}.{propertyName}是类型{Property.PropertyType.Name}而不是(从){typeof(TProperty.Name}!”派生的);
返回false;
}
规则(validator.RuleFor(t=>(TProperty)property.GetValue(t));
返回true;
}
用法示例:
class a
{
public string Prop { get; set; }
}
class b
{
public DateTime Prop { get; set; }
}
class c
{
public string Prop2 { get; set; }
}
class Validator<T> : AbstractValidator<T>
{
public Validator()
{
this.Apply<T, string>("Prop", r => r.NotEmpty().WithMessage("Prop is required"));
}
}
Console.WriteLine(new Validator<a>().Validate(new a { Prop = "AAA" }));
Console.WriteLine(new Validator<a>().Validate(new a()));
Console.WriteLine(new Validator<b>().Validate(new b { Prop = DateTime.Now }));
Console.WriteLine(new Validator<c>().Validate(new c { Prop2 = "AAA" }));
Console.WriteLine(new Validator<c>().Validate(new c { Prop2 = "AAA" }));
a类
{
公共字符串属性{get;set;}
}
b类
{
公共日期时间属性{get;set;}
}
c类
{
公共字符串Prop2{get;set;}
}
类验证器:抽象验证器
{
公共验证器()
{
this.Apply(“Prop”,r=>r.NotEmpty().WithMessage(“Prop是必需的”);
}
}
WriteLine(newvalidator().Validate(newa{Prop=“AAA”}));
Console.WriteLine(新的Validator().Validate(新的a());
WriteLine(newvalidator().Validate(new b{Prop=DateTime.Now}));
WriteLine(newvalidator().Validate(newc{Prop2=“AAA”}));
WriteLine(newvalidator().Validate(newc{Prop2=“AAA”}));
您可以使用以下扩展方法,通过反射检查传递的类型并应用指定的验证规则:
public static bool Apply<T, TProperty>(this AbstractValidator<T> validator, string propertyName, Action<IRuleBuilderInitial<T, TProperty>> rule)
{
var property = typeof(T).GetProperty(propertyName);
if (property == null)
{
Console.WriteLine($"{typeof(T).Name} does not expose property {propertyName}!");
return false;
}
if (!typeof(TProperty).IsAssignableFrom(property.PropertyType))
{
Console.WriteLine($"Property {typeof(T).Name}.{propertyName} is of type {property.PropertyType.Name} which is not (derived from) {typeof(TProperty).Name}!");
return false;
}
rule(validator.RuleFor(t => (TProperty)property.GetValue(t)));
return true;
}
公共静态bool Apply(此抽象验证器验证器、字符串属性名称、操作规则)
{
var property=typeof(T).GetProperty(propertyName);
if(属性==null)
{
WriteLine($“{typeof(T).Name}不公开属性{propertyName}!”);
返回false;
}
如果(!typeof(TProperty).IsAssignableFrom(property.PropertyType))
{
Console.WriteLine($“Property{typeof(T).Name}.{propertyName}是类型{Property.PropertyType.Name}而不是(从){typeof(TProperty.Name}!”派生的);
返回false;
}
规则(validator.RuleFor(t=>(TProperty)property.GetValue(t));
返回true;
}
用法示例:
class a
{
public string Prop { get; set; }
}
class b
{
public DateTime Prop { get; set; }
}
class c
{
public string Prop2 { get; set; }
}
class Validator<T> : AbstractValidator<T>
{
public Validator()
{
this.Apply<T, string>("Prop", r => r.NotEmpty().WithMessage("Prop is required"));
}
}
Console.WriteLine(new Validator<a>().Validate(new a { Prop = "AAA" }));
Console.WriteLine(new Validator<a>().Validate(new a()));
Console.WriteLine(new Validator<b>().Validate(new b { Prop = DateTime.Now }));
Console.WriteLine(new Validator<c>().Validate(new c { Prop2 = "AAA" }));
Console.WriteLine(new Validator<c>().Validate(new c { Prop2 = "AAA" }));
a类
{
公共字符串属性{get;set;}
}
b类
{
公共日期时间属性{get;set;}
}
c类
{
公共字符串Prop2{get;set;}
}
类验证器:抽象验证器
{
公共验证器()
{
this.Apply(“Prop”,r=>r.NotEmpty().WithMessage(“Prop是必需的”);
}
}
WriteLine(newvalidator().Validate(newa{Prop=“AAA”}));
Console.WriteLine(新的Validator().Validate(新的a());
WriteLine(newvalidator().Validate(new b{Prop=DateTime.Now}));
WriteLine(newvalidator().Validate(newc{Prop2=“AAA”}));
WriteLine(newvalidator().Validate(newc{Prop2=“AAA”}));
仔细想想,您需要做的就是重用验证器类
class AddressCreateAPIValidator : AbstractValidator<AddressCreateAPI>
{
public AddressCreateAPIValidator()
{
RuleFor(d => d.Street)
.NotEmpty().WithMessage("Address Street is required");
RuleFor(d => d.City)
.NotEmpty().WithMessage("Address City is required");
RuleFor(d => d.StateProvinceId)
.InclusiveBetween(0, int.MaxValue).WithMessage("Address State is required");
}
}
class SomeClass
{
public AddressCreateAPI Prop { get; set; }
}
class SomeClassValidator : AbstractValidator<SomeClass>
{
public SomeClassValidator()
{
RuleFor(d => d.Prop).SetValidator(new AddressCreateAPIValidator());
}
}
类地址CreateApiValidator:AbstractValidator
{
公共地址CreateApiValidator()
{
规则(d=>d.Street)
.NotEmpty().WithMessage(“需要地址街”);
规则(d=>d.City)
.NotEmpty().WithMessage(“需要地址城市”);
规则(d=>d.StateProvinceId)
.inclusiveBeween(0,int.MaxValue).WithMessage(“需要地址状态”);
}
}
上课
{
公共地址CreateAPI属性{get;set;}
}
类SomeClassValidator:AbstractValidator
{
公共类验证器()
{
RuleFor(d=>d.Prop).SetValidator(新地址CreateApiValidator());
}
}
请注意AddressCreateAPIValidator
如何提取用于验证AddressCreateAPI
类的公共逻辑,然后通过调用SetValidator
重新用于属性
如果你想创建一个通用的验证器,你可以将它与另一个答案中基于反射的方法混合使用。仔细想想,你需要做的就是重用一个验证器类
class AddressCreateAPIValidator : AbstractValidator<AddressCreateAPI>
{
public AddressCreateAPIValidator()
{
RuleFor(d => d.Street)
.NotEmpty().WithMessage("Address Street is required");
RuleFor(d => d.City)
.NotEmpty().WithMessage("Address City is required");
RuleFor(d => d.StateProvinceId)
.InclusiveBetween(0, int.MaxValue).WithMessage("Address State is required");
}
}
class SomeClass
{
public AddressCreateAPI Prop { get; set; }
}
class SomeClassValidator : AbstractValidator<SomeClass>
{
public SomeClassValidator()
{
RuleFor(d => d.Prop).SetValidator(new AddressCreateAPIValidator());
}
}
类地址CreateApiValidator:AbstractValidator
{
公共地址CreateApiValidator()
{
规则(d=>d.Street)
.NotEmpty().WithMessage(“需要地址街”);
规则(d=>d.City)
.NotEmpty().WithMessage(“需要地址城市”);
规则(d=>d.StateProvinceId)
.inclusiveBeween(0,int.MaxValue).WithMessage(“需要地址状态”);
}
}
上课
{
公共地址CreateAPI属性{get;set;}
}
类SomeClassValidator:AbstractValidator
{
公共类验证器()
{
RuleFor(d=>d.Prop).SetValidator(新地址CreateApiValidator());
}
}
请注意AddressCreateAPIValidator
如何提取用于验证AddressCreateAPI
类的公共逻辑,然后通过调用SetValidator
重新用于属性
如果您想创建一个通用的验证器,您可以将其与另一个答案中基于反射的方法混合匹配。如果
Address
属性继承自某个公共基类/接口,您可以创建一个验证所述属性的基类验证器(将模板参数缩小到实现所述类/接口的类)并从中派生验证器。如果不是-您可以创建基类,该基类使用反射检查传递的泛型参数是否公开Address
属性,并应用适当的验证规则(如果适用)。无继承。Address只是一个示例,可以是其他不同的公共p