asp.net core web api限制输入、模型验证
我想要在我的web api里限制一下模型的输入,例如我的一个模型有一个title属性,我不希望新创建title的长度超过20,我能想到的办法只有在Controller的Action里加if语句,但这样会让Controller非常难看,也不利于后面新功能的扩展。
在我需要这个功能之前,我不知道这个功能叫模型验证……还用小白提问话术百度了很久。感觉学编程可以只看书,学开发还需要有老师或者有经验的开发者的帮助。真的非常感谢我看过的所有博客、视频、教程等的作者,以及每一个愿意牺牲自己寥寥无几的休闲时间,来耐心的解决我提的小白问题,还有给我去百度查询解决方案提供查询的方向的朋友们,没有你们,我这种没有天赋,智商一般的学生,真的就只能Hello World了。
首先是官方文档:
https://docs.microsoft.com/zh-cn/aspnet/core/mvc/models/validation?view=aspnetcore-3.1
官方文档最开始的模型状态验证:
下面写着web api Controller,在Controller之前加上[ApiController]这个标签就能免去这个if语句了,我目前主要是学习web api,MVC还没来得及学,所以这里先不管了。
然后看我们真正要用的功能:
原来直接在上面加Atrribute就行,看一下基本的Attribute类型:
内置特性
以下是一些内置验证特性:
[CreditCard]:验证属性是否具有信用卡格式。
[Compare]:验证模型中的两个属性是否匹配。
[EmailAddress]:验证属性是否具有电子邮件格式。
[Phone]:验证属性是否具有电话号码格式。
[Range]:验证属性值是否在指定的范围内。
[RegularExpression]:验证属性值是否与指定的正则表达式匹配。
[Required]:验证字段是否不为 null。 请参阅 [Required] 属性,获取关于该特性的行为的详细信息。
[StringLength]:验证字符串属性值是否不超过指定长度限制。
[Url]:验证属性是否具有 URL 格式。
[Remote]:通过在服务器上调用操作方法来验证客户端上的输入。 请参阅 [Remote] 属性,获取关于该特性的行为的详细信息。
在 System.ComponentModel.DataAnnotations 命名空间中可找到验证特性的完整列表。
System.ComponentModel.DataAnnotations 命名空间(我们这里没用到,先留下链接留着后续学习):
我正在实现web api的翻页(分页)功能,我现在的需求是让queryString里输入的pageNumber或者叫pageIndex不小于1,我之前试过,如果输入小于1的,就会报500错误,但这个显然是个400错误,是他的请求是BadRequest,这个锅不应该服务器来背。
我发现上面的Range特性似乎非常合适,所以我用Range这个Attribute来搞一下:
我让PageNumber的范围在1到int能表示的最大值。(int 的System类型是Int32,short是Int16,long是Int64,所以这里我选择Int32)。
跑起来,测试一下:
StringQuery里,pageNumber给到-1,返回了400,错误信息也很清晰,达成了我们的期望。
我突然有一个新需求,我想自定义Error的输出信息,毕竟后面这个2147483647也没什么人用得到,我主要想突出页码不能小于1这个事情,当然它默认的errorMessage给出了最大最小范围,我觉得它默认的error信息是比较好的,但我还是想自定义一个。这里就要用到ErrorMessage属性:
测试一下:
PageNumber给到0,成功返回了我们自定义的错误信息。
感觉这个Attribute方式不是非常灵活,我们这里的需求是可以满足,但万一后面我们有更复杂的需求,我们要五彩斑斓的黑和五光十色的白,怎么办?有没有另外一种更灵活的方式?
官方文档给出了另外两种方式:
方式1:
方式2:
我打算使用方式2,所以我把当前的类继承IValidatableObject接口,把前面的Range Attribute注释掉。然后实现IValidatableObject接口的Validate方法:
到现在,我甚至连yield这个关键字都不知道是什么意思,因为我C#没怎么学,没办法,急着毕业找工作,赶鸭子上架,大学欠下的基础债只能慢慢补了。这个方法写完后,我们运行测试一下:
是我们想要的结果。
应该还有更牛比更通用的方式,但我们这里先不试了,用到的时候再去学,现在强行学了感觉能记住的概率也不大。
谢谢大家的浏览。