您好,欢迎来到爱站旅游。
搜索
您的当前位置:首页.NetCoreApi开发输入参数模型验证

.NetCoreApi开发输入参数模型验证

来源:爱站旅游
.NetCoreApi开发输⼊参数模型验证

参数模型验证 ⼀般是对传⼊的参数按照制定规则校验,该章节主要演⽰在服务端对传⼊参数进⾏校验校验主要包括3点:1,定义验证规则2,按照规则进⾏检查3,错误报告

1,定义验证规则

这⾥介绍3中验证⽅式:

⽅式⼀:使⽤ Data Annotations程序集,通过属性注解⽅式,例如 [Required]、[MaxLength] 等⽅式⼆:⾃定义属性 Attribute 验证

⽅式三:使⽤ FluentValidation ⽅式验证 (推荐)

⽅式⼀ 和 ⽅式⼆ 都要引⼊下边的程序集:

引⼊程序集:System.ComponentModel.Annotations 项⽬没有的需要安装⼀下该程序包

⽅式⼀:属性注解验证

优点:简单

缺点:只能作⽤在属性上、存在代码侵⼊、校验⽅式简单、验证只能在Controller的Action中使⽤,不⽀持⾮Controller中或者控制台程序的验证

1 public class ProductsDto 2 {

3 [Display(Name = \"商品编号\")]

4 [Required(ErrorMessage = \"{0}是必填项\")]

5 [StringLength(maximumLength: 10, MinimumLength = 5, ErrorMessage = \"{0}的长度范围是{2}到{1}\")] 6 public string ProductCode { get; set; } 7

8 [Display(Name = \"商品名称\")]

9 [Required(ErrorMessage = \"{0}是必填项\")]

10 [MinLength(1, ErrorMessage = \"{0}的最⼩长度是1\")]11 public string ProductName { get; set; }12

13 [Display(Name = \"商品价格\")]

14 [Required(ErrorMessage = \"{0}是必填项\")]

15 [RegularExpression(@\"^(?!.{12,}$)\\d{1,18}(\\.\\d{1,2})?$\格式不规范,{0}要保留⼩数点后1到2位\")]16 public decimal? Price { get; set; }17

18 [Display(Name = \"会员价\")]

19 [Compare(\"Price\必须和{1}相同\")]20 public decimal? VipPrice { get; set; }21

22 [Display(Name = \"状态\")]

23 [Range(0, 1, ErrorMessage = \"{0}必须是{1}或{2}\")]24 public int? Status { get; set; }2526 }

C#简单解释: Display 定义别名Required 必填项

StringLength 字符串长度验证 maximumLength: 10 最⼤长度 MinimumLength = 5 最⼩长度

ErrorMessage = \"{0}的长度范围是{2}到{1}\" -- 错误提⽰内容

{0}、{1}、{2} 是占位符,{0}表⽰当前属性 ,{1}第⼀个参数 maximumLength , {2}是第⼆个参数MinimumLength RegularExpression 定义正则表达式Compare 和其他属性进⾏⽐较

通过接⼝进⾏测试,返回错误报告如下:AddProducts(ProductsDto products)

⽅式⼆:⾃定义属性 Attribute 验证

优点:可以将验证声明到类级别上、在⽅式⼀的基础上进⼀步封装、可以进⾏复杂的规则校验

缺点:依然存在代码侵⼊(⼩到可以忽略不计),验证只能在Controller的Action中使⽤,不⽀持⾮Controller中或者控制台程序的验证定义⼀个类:LoginFilterValidationAttribute,继承 ValidationAttribute 属性,重写IsValid()⽅法

public class LoginFilterValidationAttribute : ValidationAttribute {

protected override ValidationResult IsValid(object value, ValidationContext validationContext) {

var userDto = (UsersDto)validationContext.ObjectInstance; //获取类的实例对象 //验证⽤户名不能为空

if (string.IsNullOrWhiteSpace(userDto.Username)) {

return new ValidationResult(\"⽤户名不能为空\ }

//验证密码不能为空

if (string.IsNullOrWhiteSpace(userDto.Password)) {

return new ValidationResult(\"密码不能为空\ }

//验证⼿机号不能为空

if (string.IsNullOrWhiteSpace(userDto.Mobile)) {

return new ValidationResult(\"⼿机号不能为空\ }

//⼿机号输⼊规则验证

if (!string.IsNullOrWhiteSpace(userDto.Mobile)) {

var regex = new Regex(@\"^1[3456789]\\d{9}$\"); if (!regex.IsMatch(userDto.Mobile))

returnnewValidationResult(\"⼿机号不符合规则\验证密码强度if(!string.IsNullOrWhiteSpace(userDto.Password)){//正则var regex=newRegex(@\" (?=.*[0-9]) #必须包含数字

(?=.*[a-zA-Z]) #必须包含⼩写或⼤写字母 (?=([\\x21-\\x7e]+)[^a-zA-Z0-9]) #必须包含特殊符号 .{6,16} #⾄少6个字符,最多16个字符

\是否匹配,如果不匹配则返回if(!regex.IsMatch(userDto.Password)){returnnewValidationResult(\"密码不符合规则,请重新输⼊\

C#

在Model类中直接如下声明即可:

[LoginFilterValidation] //将参数验证声明到类上public class UsersDto{

public int Userid { get; set; }

public string Username { get; set; } 。。。}

C#

通过接⼝测试,返回错误内容如下:AddUsers(UsersDto users)

⽅式三:使⽤ FluentValidation ⽅式验证 (推荐)

优点:⽀持任何场景下的模型验证(Controller层和Service层都能⽤),且不侵⼊代码,⽀持复制规则验证,规则定义类似⽅式⼆缺点:适合⼤型项⽬(个⼈感觉),⼩项⽬⽤上边两种⽅式够⽤了使⽤该⽅式需要引⼊下边程序包:FluentValidation.AspNetCore

创建⾃定义类:RegisterValidationAttribute 、继承 AbstractValidator

1 public class RegisterValidationAttribute : AbstractValidator, IModelValidator 2 {

3 public RegisterValidationAttribute() 4 {

5 //如果设置为Stop,则检测到失败的验证,则⽴即终⽌,不会继续执⾏剩余属性的验证。 6 //默认值为 Continue

7 CascadeMode = CascadeMode.Stop; 8

9 RuleFor(x => x.Username).NotEmpty().WithMessage(\"⽤户名不能为空\")

10 .Length(2, 12).WithMessage(\"⽤户名⾄少2个字符,最多12个字符\");11

12 RuleFor(x => x.Password).NotEmpty().WithMessage(\"密码不能为空\")

13 .Length(6, 16).WithMessage(\"密码长度⾄少6个字符,最多16个字符\")

14 .Must(EncryptionPassword).WithMessage(\"密码不符合规则,必须包含数字、⼩写或⼤写字母、特殊符号\");15

16 RuleFor(x => x.ConfirmPassword).NotEmpty().WithMessage(\"确认密码不能为空\")17 .Must(ComparePassword).WithMessage(\"确认密码必须跟密码⼀样\");18

19 RuleFor(x => x.Mobile).NotEmpty().WithMessage(\"⼿机号不能为空\")20 .Must(IsMobile).WithMessage(\"⼿机号格式不正确\");21 }22

23 ///

24 /// 密码强度验证25 ///

26 ///

27 private bool EncryptionPassword(string password)28 {

29 //正则

30 var regex = new Regex(@\"

31 (?=.*[0-9]) #必须包含数字

32 (?=.*[a-zA-Z]) #必须包含⼩写或⼤写字母33 (?=([\\x21-\\x7e]+)[^a-zA-Z0-9]) #必须包含特殊符号34 .{6,16} #⾄少6个字符,最多16个字符

35 \⽐较两次密码是否⼀样41/// 42/// 这⾥传的是:C

C#

使⽤⽅式很简单,如下:

1 [HttpPost]

2 public async Task RegisterUsers(UsersDto usersDto) 3 {

4 var result = new CommonResult(); 5

6 //使⽤如下两⾏代码即可

7 RegisterValidationAttribute validationRules = new RegisterValidationAttribute(); 8 ValidationResult validaResult = validationRules.Validate(usersDto); 9

10 if (validaResult.IsValid) //校验通过11 {

12 //执⾏正常的业务逻辑13 result.ResultCode = 1;14 result.ResultMsg = \"成功\";15 }

16 else //验证没通过,返回错误信息17 {

18 result.ResultCode = 0;

19 result.ResultMsg = validaResult.ToString(\"||\");20 }

21 return Ok(result);22 }

C#

测试结果,分别返回如下错误提⽰:

如果将 Stop 替换成 Continue 会发⽣什么?

1 CascadeMode = CascadeMode.Stop;2 替换成:

3 CascadeMode = CascadeMode.Continue;

C#

测试结果如下:错误信息会全部返回  

1 {

2 \"resultCode\": 0,

3 \"resultMsg\": \"'⽤户名' 不能为空。||⽤户名⾄少2个字符,最多12个字符||'密码' 不能为空。||密码长度⾄少6个字符,最多16个字符||密码不符合规则,必须包含数字、⼩写或⼤写字母、特殊符号||'验证码' 不能为空。||请输⼊4位验证码\"4 }

C#

如果你嫌每次都要实例化⼀次对象进⾏注册,你也可以使⽤全局注册,直接在 Staup 中注册即可

1 services.AddControllers()

2 //记得引⼊ using FluentValidation.AspNetCore 3 .AddFluentValidation(option => 4 {

5 //所有验证类继承该接⼝,使⽤接⼝标识 IModelValidator 批量注册

6 //option.RegisterValidatorsFromAssemblyContaining(); 7

8 //单个类注册

9 option.RegisterValidatorsFromAssemblyContaining();10 });

C#参考⽂档:

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- azee.cn 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务