MVC4 WebAPI拒绝无效的枚举值

时间:2013-04-18 11:46:28

标签: asp.net-mvc-4 asp.net-web-api

如何使JSON.NET / MVC 4 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,我想要返回错误请求状态代码。

2 个答案:

答案 0 :(得分:26)

It turns out the EnumDataTypeAttribute, which comes with the out-of-the-box ValidationAttributes in the System.ComponentModel.DataAnnotations namespace, does an Enum.Defined check.

Once I applied this attribute to my view model, out-of-range integer values failed validation:

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

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

Note: values that can be parsed into integers that are defined on the enum will still pass validation due to the default behavior of enum model binding. This means, for example, true will be parsed as 1, which would be valid for this enum. I assume characters that can be mapped to integers will also work.

If you only want one flavor of enum parsing to work, be it string or integer, consider using that specific type on your view model, and then write a custom ValidationAttribute that takes in the enum type, validating that the string or integer on your view model matches a value in the enum.

答案 1 :(得分:21)

一种选择是编写验证器:

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,但我不是相当确定应该如何使用它们。