前言
在使用参数模型验证时,根据使用人习惯的不同会选择不同的模型验证,有人有选择api自带的模型验证,有的人会重写api模型验证,有的人会用第三方控件FluentValidation.AspNetCore来验证模型,各有所爱,可以自行选择验证方式。
这里我们先介绍第二种自定义重写api的模型验证方法IsValid,下一篇在介绍第三种验证方式
以往文章回顾:
.net6使用最小api(2)——依赖注入Autofac之属性注入
.net6使用最小api(1)——依赖注入Autofac之构造函数注入
项目实战
1、先定义模型实体,如下:
/// <summary>
/// 添加会员参数,并添加验证属性
/// </summary>
[AddMemberParamValidationAttribute]
public class AddMemberParam
{
/// <summary>
/// 会员名称
/// </summary>
public string MemberName { get; set; }
/// <summary>
/// 密码
/// </summary>
public string Password { get; set; }
/// <summary>
/// 确认密码
/// </summary>
public string ConfirmPassword { get; set; }
/// <summary>
/// 会员类型
/// </summary>
public string MemberType { get; set; }
/// <summary>
/// 真实姓名
/// </summary>
public string TrueName { get; set; }
/// <summary>
/// 手机号
/// </summary>
public string Mobile { get; set; }
}
2、验证模型类方法
创建一个模型验证类为AddMemberParamValidationAttribute,并继承ValidationAttribute,代码如下:
/// <summary>
/// 自定义属性验证
/// </summary>
public class AddMemberParamValidationAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var userDto = (AddMemberParam)validationContext.ObjectInstance; //获取类的实例对象 //验证用户名不能为空
if (string.IsNullOrWhiteSpace(userDto.MemberName))
{
return new ValidationResult("用户名不能为空", new[] { nameof(userDto.MemberName) });
}
if (string.IsNullOrWhiteSpace(userDto.Password))
{
return new ValidationResult("密码不能为空", new[] { nameof(userDto.Password) });
}
if (string.IsNullOrWhiteSpace(userDto.Mobile))
{
return new ValidationResult("手机号不能为空", new[] { nameof(userDto.Mobile) });
}
if (!string.IsNullOrWhiteSpace(userDto.Mobile))
{
var regex = new Regex(@"^1[3456789]\d{9}$"); if (!regex.IsMatch(userDto.Mobile)) return new ValidationResult("手机号不符合规则", new[] { nameof(userDto.Mobile) });
}
if (!string.IsNullOrWhiteSpace(userDto.Password))
{
// 必须包含数字
//必须包含小写或大写字母
//必须包含特殊符号
//至少6个字符,最多16个字符
var regex = new Regex(@"
(?=.*[0-9])
(?=.*[a-zA-Z])
(?=([\x21-\x7e]+)[^a-zA-Z0-9])
.{6,16}", RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace);
if (!regex.IsMatch(userDto.Password))
{
return new ValidationResult("密码不符合规则,请重新输入", new[] { nameof(userDto.Password) });
}
}
if (!string.IsNullOrWhiteSpace(userDto.ConfirmPassword))
{
if (!userDto.Password.Equals(userDto.ConfirmPassword))
{
return new ValidationResult("两次输入密码不同,请重新输入", new[] {
nameof(userDto.Password),
nameof(userDto.ConfirmPassword)
});
}
}
return ValidationResult.Success;
}
}
3、控制器调用,与正常api写法一样,如下:
/// <summary>
/// 添加用户,并会自动验证模型
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
[HttpPost("Add")]
public async Task<ResponseResult> Add(AddMemberParam param)
{
var a = await _memberService.Add(param);
return a;
}
执行结果如下:
4、最小api配置,并返回统一模型结果
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
//使用自定义模型验证
options.InvalidModelStateResponseFactory = (context) =>
{
var result = new ResponseResult()
{
errno = 1,
errmsg = string.Join(Environment.NewLine, context.ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage)))
};
return new JsonResult(result);
};
});
总结
重写验证模型可以很方便对入参进行合法验证,但在实战中可能需要创建很多的入参验证类,感觉不是很方便,有的人想到会用反射来处理,个人感觉也并不友好,也会影响性能问题。
此验证与本文验证逻辑差不多,只是重写了IsValid方法,下一篇文章介绍FluentValidation.AspNetCore验证模型,三种方法大家可选择喜欢的一种,如果有更好的验证方式,欢迎一起交流学习。