记录翻身每一天
作为一个有梦想的咸鱼,在面向百度编程的时候,终于愿意花时间仔细浏览官网,步入正题:
我们先看一个方法
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movie.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
有没有很熟悉(上面为官网代码),这就是我今天要分享的模型绑定,及验证。在dotnet的时候,我们api的接口收到请求的时候,模型验证都需要使用ModelState.IsVaild来判断获取结果,请注意,我并没有说dotnet core不行,当然core你也可以这样去实现模型验证,去掉创建控制器时自带的 [ApiController] 特性就好。
扯远了,我先说我要记录的内容 ——验证特性的自定义返回
定义一个model,加上内置特性
public class UserModel
{
[Required(ErrorMessage = "名字不能为空")]
public string Name { get; set; }
[Range(18, 120, ErrorMessage = "年龄不合理")]
public int age { get; set; }
[EmailAddress(ErrorMessage = "请填写正确的Email地址")]
public string Email { get; set; }
}
上述三个特性看字面意思可以理解,提一下Range,Range(min,max,msg),这个方法的取值范围 max >= value >=min
// POST api/values
[HttpPost]
public void Post([FromBody]UserModel model)
{
}
看起来是这么一回事,先用postman请求一次
emmmm,就这么简单???,好像是的,不过这个而返回格式似乎有点不喜欢,能不能改改?当然可以
正常情况下,大部分的API都有封装返回结果,比如 {code:0,data:object,msg:""}
但是这个突然给我返回这个玩意儿,让前端怎么玩,是吧。
我们把视角移到Startup
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
//模型绑定 特性验证,自定义返回格式
services.Configure<ApiBehaviorOptions>(options =>
{
options.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 = 12001,
body = false,
msg = str
};
return new BadRequestObjectResult(result);
};
});
}
ok了,问题就是啥,统一返回格式,结果让这个模型验证给破坏了,这样就解决这个问题了
最后在补充一下[ApiController] 特性所包含的东西
- 模型绑定源推理:自动根据请求的类型识别请求参数位置:Form/Body,可省略[FromBody]等参数特性
- 自动模型验证:就是可以省略ModelState.IsVaild的判断,自动验证内置特性
- 其他的我也不知道,再去探索吧