2013-04-18 64 views
9

如何使JSON.NET/MVC 4 WebAPI拒絕枚舉沒有成員的整數值?例如:MVC4 WebAPI拒絕無效的枚舉值

如果我有這樣的模式:

public enum Colour { Red = 1 }; 

public class Model 
{ 
    public Colour Colour { get; set; } 
} 

Model Post(Model model) 
{ 
    // model.Colour could be 99, 34234234, 0 etc, etc 
} 

如果我發佈{ Color: 9999 },我結束了在那裏model.Color = 999的模式,我想返回一個Bad Request狀態代碼來代替。

回答

18

一種選擇是寫一個驗證:

public class ValidEnumValueAttribute : ValidationAttribute 
{ 
    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     Type enumType = value.GetType(); 
     bool valid = Enum.IsDefined(enumType, value); 
     if (!valid) 
     { 
      return new ValidationResult(String.Format("{0} is not a valid value for type {1}", value, enumType.Name)); 
     } 
     return ValidationResult.Success; 
    } 
} 

用途爲:

public enum Color {Red = 1, Blue = 2} 

public class Car 
{ 
    [ValidEnumValue] 
    public Color Color { get; set; } 
} 

在控制器中,ModelState.IsValidfalse
你也可以拋出一個ValidationException,如果你真的想要失敗的請求,但我不是相當當然,這是他們應該如何使用。

+1

注:我使用MVC 4來測試它,而不是Web API,但我認爲它應該是相同的。 – Kobi

+1

這對於ASP.NET Core來說在2017年仍然是一個很好的回答,是的,它完全適用於Web API。 – Technetium

+0

由於您依賴於「value」的數據類型已經是Enum類型,因此我正在努力解決這個問題,因爲這個測試怎麼會失敗?當我在WebAPI2中嘗試這段代碼時,當「垃圾」被傳入時,「value」被默認值填充,所以它當然通過了測試。就這樣說,當您利用ModelState.IsValid檢查時,WebAPI2看起來就像是開箱即用。 – retsvek

15

原來EnumDataTypeAttributeSystem.ComponentModel.DataAnnotations名稱空間中的開箱即用ValidationAttributes一起提供的Enum.Defined check

一旦我申請這個屬性來我的視圖模型,超出範圍的整數值驗證失敗:

public enum Color {Red = 1, Blue = 2} 

public class Car 
{ 
    [EnumDataType(typeof(Color))] 
    public Color Color { get; set; } 
} 

注意:可被解析成整數,這是在枚舉定義的值仍然會由於枚舉模型綁定的默認行爲而通過驗證。這意味着,例如,true將被解析爲1,這對此枚舉有效。我認爲可以映射到整數的字符也可以工作。

如果您只希望enum解析的一種風格能夠工作,無論是字符串還是整數,請考慮在您的視圖模型上使用該特定類型,然後編寫自定義ValidationAttribute,該枚舉需要枚舉類型,驗證字符串或您的視圖模型中的整數與枚舉中的值匹配。

+0

雖然上面的答案被接受爲解決方案,但這個答案對我來說就像是一種魅力。 –