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

发布于 2025-01-09 21:10:38 字数 3972 浏览 3 评论 0原文

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

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));

    }

问题是什么:

  • 第一次验证 [fooInstance.IsValid(typeof(FooMetaData2))] 是正确的(缺少 2 个必填字段) ,
  • 第二次验证调用 [fooInstance.IsValid(typeof(FooMetaData1))] 结果错误(缺少 3 个必填字段,但代码只通知我 2),似乎代码应用了 FooMetaData2 类中描述的验证而不是FooMetaData1

有人可以向我解释为什么吗? 谢谢

I need to have different validation for the same object. So I thought to use Metadatatype to define the different rules the code is below:

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(
quot;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; }
}

the validation is call in this way:

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));

    }

What is the issue:

  • first validation [fooInstance.IsValid(typeof(FooMetaData2))] is right (2 mandatory fields missing),
  • second validation call [fooInstance.IsValid(typeof(FooMetaData1))] the result is wrong (3 mandatory field missing but the code notify me only 2), it seems that the code apply the validation describe in FooMetaData2 class instead of FooMetaData1

Someone can explain to me why?
thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仅此而已 2025-01-16 21:10:38

我使用 FluentValidator 插件解决了

I solved using fluentValidator plugin

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文