应用运行时元数据类型进行验证

apply runtime metadatatype for validation

我需要对同一个对象进行不同的验证。所以我想使用元数据类型来定义代码如下的不同规则:

public class ValidateObjectAttribute : ValidationAttribute
{
    private readonly Type _validationMetaDataType;

    public ValidateObjectAttribute(Type validationMetaDataType)
    {
        _validationMetaDataType = validationMetaDataType;
    }
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {            
        var modelType = value.GetType();
        AssociatedMetadataTypeTypeDescriptionProvider associatedMetadataTypeTypeDescriptionProvider = null;
        if (_validationMetaDataType != null)
        {
            associatedMetadataTypeTypeDescriptionProvider = new AssociatedMetadataTypeTypeDescriptionProvider(modelType, _validationMetaDataType);
            TypeDescriptor.AddProvider(associatedMetadataTypeTypeDescriptionProvider, modelType);
        }

        var validationctx = new ValidationContext(value);
        var results = new List<ValidationResult>();
        Validator.TryValidateObject(value, validationctx, results, true);

        if (associatedMetadataTypeTypeDescriptionProvider != null)
        {
            TypeDescriptor.RemoveProvider(associatedMetadataTypeTypeDescriptionProvider, modelType);
            TypeDescriptor.Refresh(value);

        }

        if (results.Count == 0) return ValidationResult.Success;

        return new ValidationResult($"Validation fail for prop: {validationContext.DisplayName}");
    }

}

public class BarMetaData1
{
    [Required]
    public string BarField1;
    [Required]
    public string BarField2;
}

public class FooMetaData1
{
    [Required]
    public string FooField1;
    [Required]
    public string FooField2;
    [Required, ValidateObject(typeof(BarMetaData1))]
    public Bar FooObject1;
}

public class FooMetaData2
{
    public string FooField1;
    [Required]
    public string FooField2;
    [Required, ValidateObject(typeof(BarMetaData1))]
    public Bar FooObject1;
}

public class BaseValidation
{
    public bool IsValid(Type validationMetaDataType)
    {

        var modelType = this.GetType();
        AssociatedMetadataTypeTypeDescriptionProvider associatedMetadataTypeTypeDescriptionProvider = null;
        if (validationMetaDataType != null)
        {
            associatedMetadataTypeTypeDescriptionProvider = new AssociatedMetadataTypeTypeDescriptionProvider(modelType, validationMetaDataType);
            TypeDescriptor.AddProvider(associatedMetadataTypeTypeDescriptionProvider, modelType);
            TypeDescriptor.Refresh(this);
        }

        var validationctx = new ValidationContext(this);
        var results = new List<ValidationResult>();
        Validator.TryValidateObject(this, validationctx, results, true);

        if (associatedMetadataTypeTypeDescriptionProvider != null)
        {
            TypeDescriptor.RemoveProvider(associatedMetadataTypeTypeDescriptionProvider, modelType);
        }

        return results.Count == 0;
    }

    
}



public class Foo : BaseValidation
{
    public string FooField1 { get; set; }
    public string FooField2 { get; set; }
    public Bar FooObject1 { get; set; }
}

public class Bar
{
    public string BarField1 { get; set; }
    public string BarField2 { get; set; }
}

验证是这样调用的:

public void Index()
    {
        Foo fooInstance = new Foo()
        {
            FooObject1 = new Bar()
        };
        fooInstance.IsValid(typeof(FooMetaData2));

        fooInstance.IsValid(typeof(FooMetaData1));

        Foo fooInstance2 = new Foo()
        {
            FooObject1 = new Bar()
        };

        fooInstance2.IsValid(typeof(FooMetaData2));

    }

问题是什么:

谁能给我解释一下为什么? 谢谢

我使用 fluentValidator 插件解决了