使用System.ComponentModel.DataAnnotations验证字段数据正确性

在.NET MVC 中,当页面提交modelAction的时候,自动填充ModelState。使用ModelState.IsValid进行方便快捷的数据验证,其验证也是调用命名空间System.ComponentModel.DataAnnotations中的各种方法进行验证。但是使用非MVC架构时,就需要写很多if判断或者正则表达式,当有多个字段需要验证的的时候不知道有多少人和我一样很厌烦这种用if判断的方式。这里记录一个方法,使用System.ComponentModel.DataAnnotations来实现自己的验证model抛出相应的错误信息。
C#文档地址:System.ComponentModel.DataAnnotations

这里我们先实现一个Person类,里面包含几个简单的属性,然后指定几个Attribute

public class Person
    {
        [Required(ErrorMessage = "{0} 必须填写")]
        [DisplayName("姓名")]
        public string Name { get; set; }

        [Required(ErrorMessage = "{0} 必须填写")]
        [RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}",ErrorMessage = "邮件格式不正确")]
        public string Email { get; set; }

        [Required(ErrorMessage = "{0} 必须填写")]
        [Range(1, 100,ErrorMessage = "超出范围")]
        public int Age { get; set; }

        [Required(ErrorMessage = "{0} 必须填写")]
        [StringLength(11, MinimumLength=11, ErrorMessage = "{0}输入长度不正确")]
        public string Phone { get; set; }

        [Required(ErrorMessage = "{0} 必须填写")]
        [Range(typeof(decimal),"1000.00","2000.99")]
        public decimal Salary { get; set; }
    }

然后实现一个ValidatetionHelper静态类,这里主要用到的是Validator.TryValidateObject方法。

 public static ValidResult IsValid(object value)
        {
            ValidResult result= new ValidResult();
            try
            {
                var validationContext = new ValidationContext(value);
                var results = new List<ValidationResult>();
                var isValid = Validator.TryValidateObject(value, validationContext, results, true);

                if (!isValid)
                {
                    result.IsVaild = false;
                    result.ErrorMembers = new List<ErrorMember>();
                    foreach (var item in results)
                    {
                        result.ErrorMembers.Add(new ErrorMember()
                        {
                            ErrorMessage = item.ErrorMessage,
                            ErrorMemberName = item.MemberNames.FirstOrDefault()
                        });
                    }
                }
                else
                {
                    result.IsVaild = true;
                }
            }
            catch (Exception ex)
            {
                result.IsVaild = false;
                result.ErrorMembers = new List<ErrorMember>();
                result.ErrorMembers.Add(new ErrorMember()
                {
                    ErrorMessage =ex.Message,
                    ErrorMemberName = "Internal error"
                });
            }

            return result;
        }

其中需要的返回结果类

public class ValidResult
{
    public List<ErrorMember> ErrorMembers { get; set; }
    public bool IsVaild { get; set; }
}

public class ErrorMember
{
    public string ErrorMessage { get; set; }
    public string ErrorMemberName { get; set; }
}

实现一个测试代码,这里看到对应验证数据比使用多个if简洁很多,整个代码也十分美观。

static void Main(string[] args)
{
    Person person = new Person();
    person.Name = "";
    person.Email = "121 212 K";
    person.Phone = "2345";
    person.Salary = 3000;
    var result =ValidatetionHelper.IsValid(person);
    if (!result.IsVaild)
    {
        foreach (ErrorMember errorMember in result.ErrorMembers)
        {
            Console.WriteLine(errorMember.ErrorMemberName+":"+errorMember.ErrorMessage);
        }
    }
    Console.Read();
}

通过测试,可以看到得到正确的验证结果。

测试结果
后续有时间,把DisplayName给显示上去,那就更完美了。


DataAnnotations验证

常用的 DataAnnotations

  1. Required :属性值必须非空或者不能只是空格,如果允许全空格可以[Required(AllowEmptyStrings = true)]
  2. DisplayName :显示名 – 定义表单字段的提示名称
  3. StringLength :字符串长度不能超过给定的最大长度,也可以指定最小长度:[StringLength(10, MinimumLength=2)]
  4. Range :范围 – 数字的可输入范围[Range(10, 20)] ,属性值必须在指定的数值范围内,可以使用数值类型的最大最小值比如int.MinValue、int.MaxValue
  5. Bind :绑定 – 列出在将请求参数绑定到模型的时候,包含和不包含的字段
  6. ScaffoldColumn :支架列 - 在编辑表单的时候,需要隐藏起来的的字符[ScaffoldColumn(true|false)]
  7. Compare: 比较 - 与制定的字段值进行比较 具体见代码 [Compare(“MyOtherProperty”)]两个属性必须相同值,比如我们要求用户重复输入两次邮件地址时有用
  8. RegularExpression: 正则表达式匹配,字符串值必须匹配正则表达式,默认大小写敏感,可以使用(?i)修饰符关闭大小写敏感,比如[RegularExpression("(?i)mypattern")]
  9. DataType :在前端显示的文本框类型
  10. Remote :服务端验证
  11. [Editable(false)] //放在主键上显示不可修改

客户端验证

关于Model层数据验证的一些验证规则与相关验证属性标签小集

(1)常规验证(必填字段、字符串长度、正则表达式验证、范围验证<数值、日期>等)

  1. 必填字段
  [Required]
  public string FirstName { get; set; }
  1. 字段长度 至多n位:
  [StringLength(160)]
  public string FirstName { get; set; }

要求至少n位:

  [StringLength(160, MinimumLength=3)]
   public string FirstName { get; set; }
  1. 正则验证
  [RegularExpre ssion(@”[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})]
   public string Email { get; set; }
  1. 范围
 [Range(35,44, UIHint("IntSlider"))] //左右托动块
public int Age { get; set; }

小数的情况:

[Range(typeof(decimal),0.00,49.99)]
public decimal Price { get; set; } 
  1. 服务端参与的验证
  [Remote(“CheckUserName”, “Account”, ErrorMessage = "该姓名已存在")]
   public string UserName { get; set; }

Remote异步请求验证,在[HttpGet]时获取指定Controller里面的指定方法验证, 次方法必须是[HttpGet]标记的,返回类型为Json类型的JavaScript对象。

然后在AccountController里指定一个CheckUserName方法:

public JsonResult CheckUserName(string username)
{
      var result = Membership.FindUsersByName(username).Count == 0;

      return Json(result, JsonRequestBehavior.AllowGet);

}
  1. 比较
[RegularExpre ssion(@”[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})]

public string Email { get; set; }

[Compare(“Email”)]
public string EmailConfirm { get; set; }

public string EmailConfirm { get; set; } 
  1. 自定义错误消息

正则:

[RegularExpre ssion(@”[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4},ErrorMessage=”Email doesn’t look like a valid email address.)]

public string Email { get; set; } 

具体示例如下:

[DisplayName("分组名称")]
[Required(ErrorMessage = "请输入账号")]
[StringLength(50, ErrorMessage = "请勿输入超过 50 个字")]
public string Name { get; set; }

[DisplayName("排序字段")]
[DataType(DataType.Password)]
[Required(ErrorMessage = "请输入排序字段")]
[RegularExpre ssion(@"^([\d]+)$", ErrorMessage = "请输入正确的Email.")]
public string Sequence { get; set; }

[DisplayName("备注")]
[DataTyle(DataType.MultilineText)]//数据显示为多文本
[Required(AllowEmptyStrings=true, ErrorMessage = "请输入中文姓名")]
[StringLength(50, ErrorMessage = "请勿输入超过 50 个字")]
public string Describe { get; set; }

[DisplayName("账号")]
[Required(ErrorMessage = "请输入账号")]
[StringLength(50, ErrorMessage = "请勿输入超过 50 个字")]
public string Account { get; set; }

[DisplayName("密码")]
[DataType(DataType.Password)]
[Required(ErrorMessage = "请输入密码")]
[StringLength(50, ErrorMessage = "请勿输入超过 50 个字")]
public string Password { get; set; }

[Required]
[DataType(DataType.Password)]
[Display(Name = "Current password")]
public string OldPassword { get; set; }(PMS已有 

[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }(PMS已有)

[Display(Name = "确认密码")]
[Compare("LogPassword", ErrorMessage = "密码必须一致")]
public virtual string LogPasswordConfirm { get; set; }(PMS已有)

[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }(PMS已有)

[DisplayName("姓名")]
[Required(ErrorMessage = "请输入姓名")]
[StringLength(50, ErrorMessage = "请勿输入超过 50 个字")]
public string ChName { get; set; }  (PMS已有)

[DisplayName("昵称")]
[Required(ErrorMessage = "请输入昵称")]
[StringLength(50, ErrorMessage = "请勿输入超过 50 个字")]
public string NickName { get; set; }

[Display(Name = "出生日期")]   
//[Range(typeof(DateTime), "2011-12-31", "1950-1-1", ErrorMessage = "{0}的范围是{1}到{2}")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]//显示格式
public virtual DateTime? Birthday { get; set; } //表示值可为Null

[DisplayName("年龄")]
[Range(1, int.MaxValue, ErrorMessage = "请输入大于等于1的数")]
public int Age { get; set; }

[DisplayName("Email")]
[Required(ErrorMessage = "请输入Email")]
[StringLength(255, ErrorMessage = "请勿输入超过 255 个字")]
[RegularExpre ssion(@"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4})$", ErrorMessage = "请输入正确的Email.")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; } (PMS已有)

[DisplayName("电话号码")]
[RegularExpre ssion(@"^((0\d{2,5}-)|
public string Phone { get; set; }

[Display(Name = "身份证号码")]
[RegularExpre ssion(@"\d{17}[\d|X]|\d{15}", ErrorMessage = "{0}的格式不正确")]
public virtual string IdentityNo { get; set; }

[DisplayName("是否为管理员")]
public bool IsAdmin { get; set; }

[DisplayName("代表图示")]
[Required(ErrorMessage = "请选择代表图示")]
[Range(1, 3, ErrorMessage = "输入的值必须介于 1 到 3之间")]
public int AvatarIcon { get; set; }

[Display(Name = "逻辑删除标识")]
public virtual int IsLogicDelete { get; set; }

[DisplayName("验证码")]
public string AuthCode { get; set; }

[DisplayName("创建日期")]
public DateTime CreateTime { get; set; }

[DisplayName("网址")]
[RegularExpre ssion(@"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?", ErrorMessage = "请输入合法的网址!\n示例:https://abc.a;http://www.abc.dd")]
public string Httpaddress { get; set; }

普通文本:

[Required(ErrorMessage=”Your last name is required)]
[StringLength(160, ErrorMessage=”Your last name is too long)]
public string LastName { get; set; }

占位符:

[Required(ErrorMessage=”Your {0} is required.)]
[StringLength(160, ErrorMessage={0} is too long.)]
public string LastName { get; set; }

(2)数据库约束验证

如果不希望用户使用123456这样的过于简单的密码,可以使用check约束来实现:

ALTER TABLE staffinfoes WITH NOCHECK  ADD CONSTRAINT chk_logPassword

CHECK (logPassword NOT IN('123','123123','123456'))

其中,staffinfoes是表名称,chk_logPassword是约束名称,logPassword是列名称

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值