2011-11-04 148 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