【问题标题】:MVC4 WebAPI reject invalid enum valuesMVC4 WebAPI 拒绝无效的枚举值
【发布时间】:2013-04-18 11:46:28
【问题描述】:

如何让 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 的模型,而我想返回一个错误请求状态代码。

【问题讨论】:

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


    【解决方案1】:

    事实证明,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,这将对此枚举有效。我假设可以映射到整数的字符也可以工作。

    如果您只想使用一种枚举解析方式,无论是字符串还是整数,请考虑在您的视图模型上使用该特定类型,然后编写一个接受枚举类型的自定义 ValidationAttribute,验证该字符串视图模型上的或整数与枚举中的值匹配。

    【讨论】:

    • 虽然上述答案被接受为解决方案,但这个答案对我来说就像一个魅力。
    • 在 WebApi 中不适合我 - 这可能仅适用于 MVC 控制器吗?
    • @mcintyre321 只要其他验证属性正在运行,它应该工作。就 MVC 与 WebAPI 而言,此属性没有什么特别之处。
    • 我很高兴我向下滚动找到了这个答案。我几乎写了(好吧,复制和粘贴......)自定义代码,而无需任何代码!
    【解决方案2】:

    一种选择是编写一个验证器:

    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.IsValid 将是 false
    如果您真的想使请求失败,您也可以抛出ValidationException,但我不太确定应该如何使用它们。

    【讨论】:

    • 注:我是用MVC 4测试的,不是Web API,但我觉得应该是一样的。
    • 这仍然是 2017 年 ASP.NET Core 的一个很好的答案,是的,对于 Web API 完全有效。
    • 我正在努力解决这如何工作,因为您依赖“值”的数据类型已经是 Enum 类型,那么这个测试怎么会失败?当我在 WebAPI2 中尝试此代码时,“值”在传入垃圾时填充了默认值,因此它当然通过了测试。话虽如此,当您利用对 ModelState.IsValid 的检查时,WebAPI2 似乎开箱即用。
    • 我现在正在努力解决的问题是(A)我无法控制该失败的消息,并且(B)当未提供枚举值时使用不起作用[Required] 属性似乎没有解决(因为使用默认值的问题相同)
    • @retsvek - 这些都是很好的问题。我建议您发布一个新问题(或两个),这样您会得到更好的答案。 (这个答案已经快 4 岁了!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    相关资源
    最近更新 更多