自定义 DataTypeAttribute 未正确触发验证

发布于 2024-09-29 21:35:56 字数 1339 浏览 8 评论 0原文

与此问题相关,

我创建了自己的 DateValidationAttibute 以确保字符串采用有效的日期格式(例如,MM/DD/YYYY)

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public class DateValidationAttribute : DataTypeAttribute
{
    public DateValidationAttribute() : base(DataType.Date){}

    //MM/DD/YYYY, MM-DD-YYYY
    public override bool IsValid(object value)
    {
        //validation logic
    }
}

我正在尝试使用此代码测试此属性

    [Test]
    public void Test()
    {
        var invalidObject = new TestValidation {DateField = "bah"};
        var validationContext = new ValidationContext(invalidObject, null, null);
        var validationResults = new System.Collections.Generic.List<ValidationResult>();

        bool result = Validator.TryValidateObject(invalidObject, validationContext, validationResults);

        Assert.IsFalse(result);
        Assert.AreEqual(1, validationResults.Count);
    }

    private class TestValidation
    {
        [DateValidation(ErrorMessage = "Invalid Date!")]
        public string DateField { get; set; }
    }

不幸的是这不起作用。我在 DateValidationAttribute 构造函数和 IsValid 方法处放置了一个断点。它肯定会命中构造函数,但永远不会命中 IsValid 方法。有什么想法吗?

Related to this question

I have created my own DateValidationAttibute to make sure a string is in a valid date format (e.g., MM/DD/YYYY)

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public class DateValidationAttribute : DataTypeAttribute
{
    public DateValidationAttribute() : base(DataType.Date){}

    //MM/DD/YYYY, MM-DD-YYYY
    public override bool IsValid(object value)
    {
        //validation logic
    }
}

I am trying to test this attribute with this code

    [Test]
    public void Test()
    {
        var invalidObject = new TestValidation {DateField = "bah"};
        var validationContext = new ValidationContext(invalidObject, null, null);
        var validationResults = new System.Collections.Generic.List<ValidationResult>();

        bool result = Validator.TryValidateObject(invalidObject, validationContext, validationResults);

        Assert.IsFalse(result);
        Assert.AreEqual(1, validationResults.Count);
    }

    private class TestValidation
    {
        [DateValidation(ErrorMessage = "Invalid Date!")]
        public string DateField { get; set; }
    }

Unfortunately this isn't working. I put a breakpoint at the DateValidationAttribute constructor, and the IsValid method. It definitely hits the constructor, but never hits the IsValid method. Any ideas?

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

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

发布评论

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

评论(3

天生の放荡 2024-10-06 21:35:56

TryValidateObject 方法有一个重载,可以采用布尔值 validateAllProperties 作为第四个参数。如果不指定,则默认为 false,即仅检查某些属性。

[Test]
public void Test()
{
    var invalidObject = new TestValidation {DateField = "bah"};
    var validationContext = new ValidationContext(invalidObject, null, null);
    var validationResults = new System.Collections.Generic.List<ValidationResult>();

    //Validate all attributes
    bool result = Validator.TryValidateObject(invalidObject, validationContext, validationResults, true);

    Assert.IsFalse(result);
    Assert.AreEqual(1, validationResults.Count);
}

The method TryValidateObject has an overload that can take a boolean validateAllProperties as a fourth parameter. If not specified, it defaults to false, which is when it only checks some attributes.

[Test]
public void Test()
{
    var invalidObject = new TestValidation {DateField = "bah"};
    var validationContext = new ValidationContext(invalidObject, null, null);
    var validationResults = new System.Collections.Generic.List<ValidationResult>();

    //Validate all attributes
    bool result = Validator.TryValidateObject(invalidObject, validationContext, validationResults, true);

    Assert.IsFalse(result);
    Assert.AreEqual(1, validationResults.Count);
}
故事灯 2024-10-06 21:35:56

我从未尝试过使用 DataTypeAttribute 类创建 ValidationAttributes,我不确定这是否错误,但扩展 ValidationAttribute 类一直对我有用。

“默认情况下,DataTypeAttribute 不进行任何验证。但它确实会影响有关数据呈现方式的模板。”摘自这个问题

示例:

[AttributeUsage(AttributeTargets.Field,  AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class MyCustomAttribute : ValidationAttribute
{
  public MyCustomAttribute()
    : base("Custom Error Message: {0}")
  {
  }

  public override bool IsValid(object value)
  {
    return true;
  }
}

I've never tried creating ValidationAttributes using the DataTypeAttribute class and I'm not sure if this is wrong but extending the ValidationAttribute class has always worked for me.

"DataTypeAttribute doesn't do any validation by default. But it does influence templates regarding how the data is presented." taken from this question

Example :

[AttributeUsage(AttributeTargets.Field,  AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class MyCustomAttribute : ValidationAttribute
{
  public MyCustomAttribute()
    : base("Custom Error Message: {0}")
  {
  }

  public override bool IsValid(object value)
  {
    return true;
  }
}
╄→承喏 2024-10-06 21:35:56

从 MSDN 链接 中,请注意,只有必填字段才会被验证,<强>不任何其他验证。

此方法评估每个
ValidationAttribute 实例是
附加到对象类型。它还
检查每个属性是否是
标有RequiredAttribute的是
假如。 它不递归
验证属性值
对象

您将需要将测试更改为此,请注意,我们正在 ValidationContext 上设置 MemberName 并告诉验证器验证 invalidObject.DateField 属性。

[Test]
public void Test()
{
     var invalidObject = new TestValidation { DateField = "bah" };
     var validationContext = new ValidationContext(invalidObject,null , null){MemberName = "DateField"};
     var validationResults = new System.Collections.Generic.List<ValidationResult>();

     var result = Validator.TryValidateProperty(invalidObject.DateField, validationContext, validationResults);

    Assert.IsFalse(result);
    Assert.AreEqual(1, validationResults.Count);
}

From MSDN link, note that only the required fields will be validated, NOT any other validation.

This method evaluates each
ValidationAttribute instance that is
attached to the object type. It also
checks whether each property that is
marked with RequiredAttribute is
provided. It does not recursively
validate the property values of the
object
.

You will want to change your test to this, note that we are setting the MemberName on the ValidationContext and telling the Validator to validate the invalidObject.DateField property.

[Test]
public void Test()
{
     var invalidObject = new TestValidation { DateField = "bah" };
     var validationContext = new ValidationContext(invalidObject,null , null){MemberName = "DateField"};
     var validationResults = new System.Collections.Generic.List<ValidationResult>();

     var result = Validator.TryValidateProperty(invalidObject.DateField, validationContext, validationResults);

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