写点什么

手把手教你 AspNetCore WebApi:数据验证

用户头像
AI代笔
关注
发布于: 2020 年 10 月 10 日

前言

小明最近又遇到麻烦了,小红希望对接接口传送的数据进行验证,既然是小红要求,那小明说什么都得满足呀,这还不简单嘛。



传统验证



[HttpPost]
public async Task<ActionResult<Todo>> PostTodo(Todo todo)
{
if (string.IsNullOrEmpty(todo.Name))
{
return Ok("名称不能为空");
}
context.Todo.Add(todo);
await context.SaveChangesAsync();

return CreatedAtAction("GetTodo", new { id = todo.Id }, todo);
}



小明写着写着发现这样写,很多接口相同得地方都要写,使得代码比较臃肿。



使用模型验证

在参数模型上打上注解



namespace App001.Models
{
/// <summary>
/// 待办事项
/// </summary>
public class Todo
{
/// <summary>
/// ID
/// </summary>
public Guid Id { get; set; }
/// <summary>
/// 名称
/// </summary>
[Required(ErrorMessage = "名称不能为空")]
public string Name { get; set; }
}
}



Postman测试Name传值未空时,则返回:



{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|df184e36-4e11844dfd38a626.",
"errors": {
"Name": [
"名称不能为空"
]
}
}



注意Web API 控制器具有 [ApiController] 特性,则它们不必检查ModelState.IsValid。在此情况下,如果模型状态无效,将返回包含错误详细信息的自动 HTTP 400 响应。



内置特性

  • [CreditCard]:验证属性是否具有信用卡格式。

  • [Compare]:验证模型中的两个属性是否匹配。

  • [EmailAddress]:验证属性是否具有电子邮件格式。

  • [Phone]:验证属性是否具有电话号码格式。

  • [Range]:验证属性值是否在指定的范围内。

  • [RegularExpression]:验证属性值是否与指定的正则表达式匹配。

  • [Required]:验证字段是否不为 null。

  • [StringLength]:验证字符串属性值是否不超过指定长度限制。

  • [Url]:验证属性是否具有 URL 格式。

  • [Remote]:通过在服务器上调用操作方法来验证客户端上的输入。



Error messages

通过验证特性可以指定要为无效输入显示的错误消息。 例如:



[Required(ErrorMessage = "名称不能为空")]



使用自定义返回消息格式

有两种方式:

  1. 使用自定义过滤器

  2. 使用默认模型验证,需要在控制器上面加上【ApiController】。



使用自定义过滤器

首先,创建ModelValidateActionFilterAttribute过滤器。



public class ModelValidateActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
//获取验证失败的模型字段
var errors = context.ModelState
.Where(e => e.Value.Errors.Count > 0)
.Select(e => e.Value.Errors.First().ErrorMessage)
.ToList();

var str = string.Join("|", errors);

//设置返回内容
var result = new
{
Code = 10000,
Msg = "未通过数据验证。",
FullMsg = str
};

context.Result = new BadRequestObjectResult(result);
}

}
}



然后,Startup.ConfigureServices将过滤器添加到控制器中并关闭默认模型验证,另外我们还添加了AddNewtonsoftJson。



//关闭默认模型验证
services.Configure<ApiBehaviorOptions>(opt => opt.SuppressModelStateInvalidFilter = true);
services.AddControllers(opt =>
{
//添加过滤器
opt.Filters.Add(typeof(ModelValidateActionFilterAttribute));
}).AddNewtonsoftJson(opt =>
{
//json字符串大小写原样输出
opt.SerializerSettings.ContractResolver = new DefaultContractResolver();
});



最后,我们看一下返回效果:



{
"Code": 10000,
"Msg": "未通过数据验证。",
"FullMsg": "名称不能为空。"
}



使用默认模型验证



services.Configure<ApiBehaviorOptions>(opt =>
{
opt.InvalidModelStateResponseFactory = actionContext =>
{
//获取验证失败的模型字段
var errors = actionContext.ModelState
.Where(e => e.Value.Errors.Count > 0)
.Select(e => e.Value.Errors.First().ErrorMessage)
.ToList();

var str = string.Join("|", errors);

//设置返回内容
var result = new
{
Code = 10000,
Msg = "未通过数据验证。",
FullMsg = str
};

return new BadRequestObjectResult(result);
};
});



小结

目前为止,小明把数据验证也搞定了,是不是so easy!



发布于: 2020 年 10 月 10 日阅读数: 33
用户头像

AI代笔

关注

分享机器人写作、人工智能写作等技术 2020.09.09 加入

邮箱:1282301776@qq.com 网站:https://www.aidaibi.net 代码:https://github.com/zcqiand

评论

发布
暂无评论
手把手教你AspNetCore WebApi:数据验证