Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# FluentValidation如何创建公共零件_C#_Fluentvalidation - Fatal编程技术网

C# FluentValidation如何创建公共零件

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

我有一个抽象(没关系)类:

和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 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