简体   繁体   English

C#类属性验证器了解相邻的验证器

[英]C# class property validators knowing about neighboring validators

Given a class with properties, and writing custom validators such as FooExists , I'd like to be able to view neighboring validation decorators within my FooExists functionality. 给定一个具有属性的类,并编写自定义验证器(例如FooExists ,我希望能够在FooExists功能中查看相邻的验证装饰器。 Unless there's a smarter thing I should be doing instead. 除非有更聪明的事情,否则我应该做。

I have custom validators I throw on top of properties in a variety of classes. 我在各种类的属性之上都添加了自定义验证器。 In some cases I pair it with [Required] . 在某些情况下,我将其与[Required]配对。

In the scenario where it's not required , I'd like to be able to check that within my overriden IsValid , and handle it differently. 在它不是必需的情况下,我想能够检查我的被覆盖的范围内IsValid ,并且不同的方式处理它。

public class ExampleDTO
{
    [Required]
    [FooExists]
    public string Foo { get; set; }

    public string Bar { get; set; }
}

public class AnotherExampleDTO
{
    [FooExists]
    public string Foo { get; set; }

    public bool IsMoo { get; set; }
}

[AttributeUsage(AttributeTargets.Property)]
sealed public class FooExistsAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        // ideally I could check if this property is required via [Required]

        // look things up in the database, return true or false
        return true;
    }
}

This reason for all this is, if I make a POST to a controller receiving an ExampleDTO , it will be validated such that Foo exists (Required), and that the value is legal (FooExists). 所有这些的原因是,如果我ExampleDTO收到ExampleDTO的控制器进行POST,则会对其进行验证,以确保Foo存在(必需),并且该值合法(FooExists)。 However, if I make a POST to a controller receiving AnotherExampleDTO , and leave out the Foo parameter (because it's not required), I don't want it to fail FooExists . 但是,如果我对接收AnotherExampleDTO的控制器进行POST并忽略Foo参数(因为它不是必需的),则我不希望它失败FooExists FooExists can check if it's null, but really I want to say "if not required and null, that's fine, return true." FooExists可以检查它是否为null,但实际上我想说“如果不是必需的,则为null,可以,返回true”。

I have toyed around with adding my own Required property, so that I can [FooExists(Required=true)] [FooExists(Required=true)]添加了自己的Required属性,以便可以[FooExists(Required=true)]

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
sealed public class FooExistsAttribute : ValidationAttribute
{
    public bool Required { get; set; }

    public override bool IsValid(object value)
    {
        if (!Required && value == null)
            return true

        // look things up in the database, return true or false
        return true;
    }
}

But this feels wrong, not to mention I lose the free [Required] error message. 但这感觉不对,更不用说我丢失了免费的[Required]错误消息。

I'm also trying to avoid (in this case) inheriting IValidatableObject in my DTO and putting this in the model: 我还试图避免(在这种情况下)在我的DTO中继承IValidatableObject并将其放入模型中:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    // I could check all of the class properties in here
}

Short answer: No 简短答案:否

Long answer: You could get this behavior with some custom code and reflection, but in the case you have outlined that isn't needed. 长答案:您可以通过一些自定义代码和反射来获得此行为,但是如果您已概述了这些内容,则不需要这样做。

The [Required] attribute allows you to specify whether empty/null strings are valid. [Required]属性允许您指定空/空字符串是否有效。 It also only validates strings. 它还仅验证字符串。 To validate an integer you need Range . 要验证整数,您需要Range

See: RequiredAttribute on MSDN , RangeAttribute on MSDN 请参阅: MSDN 上的 RequiredAttribute,MSDN上的 RangeAttribute

From your example, [FooExists] as I said, isn't useful at all because you are working with an integer value. 在您的示例中,我所说的[FooExists]根本没有用,因为您使用的是整数值。 If a field isn't required then there is no need for an attribute at all. 如果不需要字段,则根本不需要属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM