【问题标题】:Validate model on specific string values验证特定字符串值的模型
【发布时间】:2016-01-04 09:11:55
【问题描述】:

我正在开发一个 Web API 2 项目。除了要求某些属性是必需的外,有些只能具有特定值。 一种选择是我可以尝试将模型保存到数据库(EF6)并在保存时创建一些逻辑,但我认为最好在调用数据库之前验证是否设置了正确的值。数据注释是否提供了像 Range 这样的属性,但又提供了特定的字符串值,如下例所示?还是我必须编写自己的验证器属性?

public class Person {
    public int PersonID { get; set; }

    [Required]
    public string FirstName { get; set; }
    public string LastName { get; set; }

    [StringRange("M","F")]
    public string Gender { get; set; }
}

在上面的示例中,当向控制器发送帖子时,唯一接受的值是“M”或“F”。

【问题讨论】:

标签: c# asp.net-web-api2


【解决方案1】:

为了验证 Gender 属性,我通过创建一个新类(属性)创建了一个自定义验证属性:

using System;
using System.Collections.Generic;
using System.Web;
using System.ComponentModel.DataAnnotations;    

namespace MyProject.Models.Validation
{

    public class StringRangeAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {

            if(value.ToString() == "M" || value.ToString() == "F")
            {
                return ValidationResult.Success;
            }


            return new ValidationResult("Please enter a correct value");
        }
    }
}

【讨论】:

    【解决方案2】:

    如果将来有人偶然发现此线程,我会更进一步并添加一个公共字符串数组属性,以接受验证过滤器中的允许值。这将允许您在属性装饰器中提供一组有效字符串。

    这样,您现在有了一个通用的可重用属性,您可以随时使用它来将模型字符串属性限制为一组预定义的值。由于它是一个验证属性,因此您也可以使用更丰富的错误消息来装饰它。

    示例用法:

    public class Person {
        [StringRange(AllowableValues = new[] { "M", "F" }, ErrorMessage = "Gender must be either 'M' or 'F'.")]
        public string Gender { get;set; }
    }
    

    字符串属性:

    public class StringRangeAttribute : ValidationAttribute
    {
        public string[] AllowableValues { get; set; }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (AllowableValues?.Contains(value?.ToString()) == true)
            {
                return ValidationResult.Success;
            }
    
            var msg = $"Please enter one of the allowable values: {string.Join(", ", (AllowableValues ?? new string[] { "No allowable values found" }))}.";
            return new ValidationResult(msg);
        }
    }
    

    【讨论】:

    • For AllowableValues?.Contains() 我对 AllowableValues?.Any() 的运气更好。我喜欢这个解决方案,西蒙!
    • 属性中定义的ErrorMessage被忽略,当你没有输入任何允许的值时,显示msg变量的内容。
    【解决方案3】:

    你可以像这样使用正则表达式:

    [RegularExpression("M|F", ErrorMessage = "The Gender must be either 'M' or 'F' only.")]
    public string Gender { get; set; }
    

    但在我的 api 中,当我传递数据时它会显示错误消息 所以你可以添加

    [StringLength(1, MinimumLength = 1, ErrorMessage = "The Gender must be 1 characters.")]
    

    最终代码:

    [StringLength(1, MinimumLength = 1, ErrorMessage = "The Gender must be 1 characters.")]
    [RegularExpression("M|F", ErrorMessage = "The Gender must be either 'M' or 'F' only.")]
    public string Gender { get; set; }
    

    【讨论】:

    • 不错。快速'n'脏,非常适合我目前的项目!
    • 如果你通过了m|f还有什么。它会失败。需要在小写两个中添加什么才能通过?
    【解决方案4】:
    [Required]
    [RegularExpression("value1|value2|value3|...", ErrorMessage = "YourMessageHere")]
    public string Gender { get; set; }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-14
      • 2012-12-21
      • 1970-01-01
      • 2014-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多