2011-11-04 104 views
3

我有一些非常疯狂的自定义验证我正在处理。基本上,根据选择的下拉菜单,这将确定哪些值针对目标属性进行了验证。重复在同一个属性上的相同DataAnnotation属性

例如,我有以下的下拉菜单:

1 =汽车
2 =卡车

在我的自定义验证,如果选择汽车,然后该值不能超过20.如果选择卡车,价值不能超过40.

所以我的属性需要看起来像这样:

[ValueBelowIf("1", 20)] 
[ValueBelowIf("2", 40)] 
public int Value { get; set; } 

当然,即使得到它的编译,我必须设置这个对我的自定义属性:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] 
public class ValueBelowIfAttribute : ValidationAttribute, IClientValidatable 

然而,似乎只有第一个属性被绑定 - 第二个被忽略。

我在做什么错?

+0

类名字的拼写是错误的。 –

+1

谢谢,它只是在我的例子中拼错了(我用手模糊了它)。 –

+0

继承?下拉将是鉴别器字段,并且每个派生类可以具有不同的验证属性。 – jkoreska

回答

0

由于C#Attrbiutes是有限的常量,我发现做到这一点的最好办法是提供所有的值通过构造函数作为单独的值。这很丑陋,但它是唯一可行的方法。

例如:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] 
public class ValueBelowIfAttribute : ValidationAttribute, IClientValidatable 
{ 
    public string IfValue { get; set; } 
    public int BelowValue { get; set; } 
    public string IfValue2 { get; set; } 
    public int BelowValue2 { get; set; } 
    public string IfValue3 { get; set; } 
    public int BelowValue3 { get; set; } 

    public ValueBelowIfAttribute(string ifValue, int belowValue) 
    { 
     // do stuff 
    } 

    public ValueBelowIfAttribute(string ifValue, int belowValue, string ifValue2, int belowValue2) 
    { 
     // do stuff 
    } 

    public ValueBelowIfAttribute(string ifValue, int belowValue, string ifValue2, int belowValue2, string ifValue3, int belowValue3) 
    { 
     // do stuff 
    } 
} 
+0

这不会回答原因,尽管“AllowMultiple = true”,该属性不会多次应用于您的示例中的成员。 – bojingo

0

您正试图将类级验证逻辑实现为属性验证技术。不要那样做!使用正确的类验证机制来代替,例如实现IValidatableObject,或使用FluentValidation

+1

我这样做是为了能够连接不引人注目的客户端验证。有没有一种方法可以实现全班级验证? –

1

你需要重写的TypeId默认实现。 MVC的验证器将仅基于它的TypeId值评估每个唯一属性。

更改您的属性实施以下内容,它会工作:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] 
public class ValueBelowIfAttribute : ValidationAttribute, IClientValidatable 
{ 
    private object _typeId = new object(); 
    public override object TypeId 
    { 
    get { return this._typeId; } 
    } 
    // OTHER CODE 
} 

从我所收集,的AllowMultiple,至少在MVC的情况下,只是告诉编译器,这个属性是有效的出现多次,但它是TypeId,用于控制在运行时如何评估这些属性。

这可能很有用,因为您可以静态地(在编译时)允许多次应用相同的属性类型,但在运行时会忽略逻辑上重复的属性。例如,在我的示例中,不是返回保证唯一的新对象(),而是返回属性参数的哈希码。在这种情况下,如果您这样做:

[ValueBelowIf("1", 20)] 
[ValueBelowIf("2", 40)] 
[ValueBelowIf("2", 40)] 
public int Value { get; set; } 

第二个[ValueBelowIf("2", 40)]将不会被评估。

阅读,我通过这个答案来这里更多的细节: http://www.paraesthesia.com/archive/2010/03/02/the-importance-of-typeid-in-asp.net-mvc-dataannotations-validation-attributes.aspx

相关问题