【问题标题】:Custom DataAnnotation IsValid Not Called未调用自定义 DataAnnotation IsValid
【发布时间】:2016-09-21 05:18:08
【问题描述】:

背景

大家好,

基本上,我在 .NET Core 类库中编写自定义数据注释,它将验证 IEnumerable 是否具有至少一定数量的元素。


问题

由于某种原因,在运行验证时,永远不会调用 IsValid。我已经找到了一些关于这个问题的其他 SO 问题,但他们都有与我不同的问题(基本上,他们实际上并没有验证他们的对象)。但是,我正在验证我的对象(调用 Validator.TryValidateObject(...)),但从未调用过 IsValid。

如果我使用任何开箱即用的验证属性(例如必需),它会按预期运行。


守则

MinElementsAttribute.cs

public class MinElementsAttribute : ValidationAttribute
{
    readonly int minElements;

    public MinElementsAttribute(int minElements) : base($"Collection must have a size of at least {minElements}")
    {
        this.minElements = minElements;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var list = value as IEnumerable<object>;

        if(list == null || list.Count() < this.minElements)
        {
            return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
        }

        return ValidationResult.Success;
    }
}

MinElementsTests.cs

[Fact]
public void TestValidation()
{
    var validationResults = new List<ValidationResult>();
    var testObject = new TestObject();

    // Should be false since I have not added anything to the list
    var isValid = Validator.TryValidateObject(testObject, new ValidationContext(testObject), validationResults);

    // Fails since isValid comes back as true because IsValid on MinElementsAttribute is never called
    Assert.False(isValid);
    Assert.NotEmpty(validationResults);
}

internal class TestObject
{
    public TestObject()
    {
        this.StringList = new List<string>();
    }

    [MinElements(3)]
    public List<string> StringList { get; set; }
}

编辑:解决方案

请查看已接受的解决方案答案。我还想补充一点,通过将继承更改为来自 RequiredAttribute 而不是 ValidationAttribute,您可以隐式地强制验证所有对象属性。

【问题讨论】:

  • 请添加testobject类?
  • 在我最近的编辑中它就在那里 :)

标签: c# validation


【解决方案1】:

Validator.TryValidateObject 类有一些重载方法。你想用这个:

public static bool TryValidateObject(object instance, ValidationContext validationContext, ICollection<ValidationResult> validationResults, bool validateAllProperties);

来自MSDN article

validateAllProperties
类型:System.Boolean
true 验证所有属性; 如果为 false,则仅验证必需的属性。

您必须使用此方法,因为您的属性不是从 RequiredAttribute 类派生的。

我的示例

var validationResults = new List<ValidationResult>();            
var testObject = new TestObject();
ValidationContext contexts = new ValidationContext(testObject, null, null);            
var isValid = Validator.TryValidateObject(testObject, contexts, validationResults, true);

【讨论】:

  • 不错的答案!我进行了编辑以清理语法、格式,并将 URL 更改为指向文档的英文版本。
  • 这太棒了!我不知道从 RequiredAttribute 派生来隐式地强制验证对象上的所有属性(这是我想要的)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多