新闻中心
.NET Web API如何进行模型验证_Web API模型验证实现方式
答案:.NET Web API 模型验证通过数据注解、自定义特性、IValidatableObject 和全局过滤器实现,确保数据合法性。使用 [Required]、[StringLength] 等特性可自动验证字段;自定义 ValidationAttribute 支持复杂规则如用户名不含邮箱前缀;IValidatableObject 用于跨字段验证如密码一致性;通过全局 ModelStateValidationFilter 统一处理验证失败响应,避免重复代码,提升接口健壮性与可维护性。

.NET Web API 中的模型验证是确保客户端提交的数据符合预期结构和规则的关键环节。通过合理的验证机制,可以减少错误数据进入业务逻辑层,提升接口的健壮性和安全性。实现模型验证有多种方式,最常用的是基于数据注解(Data Annotations)和手动验证,也可结合自定义验证逻辑或使用第三方库增强灵活性。
使用数据注解进行模型验证
这是最简单且广泛使用的方式。在模型类的属性上添加特性(Attributes),由框架自动触发验证。
- [Required]:标记字段为必填项
- [StringLength]:限制字符串长度
- [Range]:数值范围限制
- [EmailAddress]:验证邮箱格式
- [RegularExpression]:使用正则表达式校验格式
例如:
public class UserDto
{
[Required(ErrorMessage = "姓名不能为空")]
[StringLength(50, ErrorMessage = "姓名不能超过50个字符")]
public string Name { get; set; }
[Required]
[EmailAddress(ErrorMessage = "邮箱格式不正确")]
public string Email { get; set; }
[Range(18, 100, ErrorMessage = "年龄必须在18到100之间")]
public int Age { get; set; }
}
控制器中可通过 ModelState.IsValid 判断验证是否通过:
[HttpPost]
public IActionResult Create([FromBody] UserDto user)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// 处理逻辑
return Ok();
}
自定义验证逻辑
当内置注解无法满足需求时,可创建自定义验证特性。继承 ValidationAttribute 并重写 IsValid 方法。
例如,要求用户名不能与邮箱前缀相同:
public class NoEmailPrefixInNameAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var model = (UserDto)validationContext.ObjectInstance;
if (model.Name != null && model.Email != null)
{
var emailPrefix
= model.Email.Split('@')[0];
if (model.Name.Contains(emailPrefix))
{
return new ValidationResult("用户名不能包含邮箱前缀");
}
}
return ValidationResult.Success;
}
}
将该特性应用到模型:
[NoEmailPrefixInName]
public class UserDto { ... }
使用 IValidatableObject 接口
对于跨字段或多条件组合验证,实现 IValidatableObject 接口更合适。
Perplexity
Perplexity是一个ChatGPT和谷歌结合的超级工具,可以让你在浏览互联网时提出问题或获得即时摘要
302
查看详情
修改模型类:
public class UserDto : IValidatableObject
{
public string Password { get; set; }
public string ConfirmPassword { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Password != ConfirmPassword)
{
yield return new ValidationResult("两次密码输入不一致", new[] { nameof(ConfirmPassword) });
}
}
}
这种方式适合需要访问整个对象实例的复杂验证场景。
全局处理验证失败响应
为了避免每个 Action 都重复写 if (!ModelState.IsValid),可以通过过滤器统一处理。
注册全局过滤器,在 Program.cs 或 Startup.cs 中配置:
builder.Services.AddControllers(options =>
{
options.Filters.Add(new ModelStateValidationFilter());
});
自定义过滤器示例:
public class ModelStateValidationFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
context.Result = new BadRequestObjectResult(context.ModelState);
}
}
}
这样所有请求都会自动检查模型状态并返回标准化错误信息。
基本上就这些。合理使用数据注解、自定义特性、IValidatableObject 和全局过滤器,就能构建出清晰可靠的 Web API 模型验证体系。关键在于根据实际场景选择合适的方式,保持代码简洁且易于维护。
以上就是.NET Web API如何进行模型验证_Web API模型验证实现方式的详细内容,更多请关注其它相关文章!
# 互联网
# 网站推广用什么指标好呢
# 泰州网站建设银行理财
# 乐亭个人网站建设对象是
# 如何做好seo 广告
# 鹿泉区b2b网站推广价钱
# 本溪营销网站优化多少钱
# 容桂网站建设教程
# 地坪网站建设免费咨询
# 金华清香型白酒网站建设
# 平凉专业的网站建设团队
# 两次
# 就能
# word
# 这是
# 是一个
# 的是
# 表单
# 两种
# 自定义
# red
# .net
# 邮箱
# ai
# 正则表达式
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
Surface怎么安装系统 微软Surface Pro U盘重装win11教程
Go语言中JSON数据解析与字段访问教程
composer 和 npm/yarn 在管理依赖方面有什么核心思想差异?
UE5.7引擎表现爆炸优化无敌!5090跑4K稳定60FPS
Win10快速启动功能利弊分析 Win10开启或关闭快速启动教程【技巧】
Win10系统怎么查看已安装更新_Win10卸载有问题的更新补丁
sublime如何处理大型CSV文件的列对齐_sublime高级表格编辑插件指南
163邮箱网页版入口导航平台 163邮箱网页版登录入口官网导航
蛙漫画网页版全站入口 蛙漫热门作品免费浏览
XML中包含HTML标签导致解析错误? 正确嵌入非XML数据的两种方法
126邮箱手机版登录官网2026_126手机邮箱免费入口最新
零跑汽车11月交付量达70327台 实现连续9个月正增长
php源码怎么看淘宝客系统_看php源码淘宝客系统技巧
如何使用J*aScript精确选择并批量修改特定父元素下子链接的样式
高德地图总提示网络异常怎么办 高德地图离线导航设置与网络排查方法
12306选座怎么选到特殊座位_12306特殊座位选择注意事项
cad怎么合并重叠的线段_cad清理重复重叠线条的操作方法
深入理解Go语言中的指针类型:以*string为例
css元素hover动画延迟生效怎么办_使用animation-delay调整触发时间
一加Ace 6T实拍样张首次公布!李杰:主摄实力完全看齐4K档性能旗舰
优化LangChain文档加载与ChromaDB集成:解决多文档处理与分块问题
谷歌google账号注册详细步骤 谷歌账号注册官方教程
邮政快递包裹最新位置 邮政快递实时追踪入口
C++ vector二维数组定义_C++ vector of vector用法
印象笔记如何设离线包出差查阅_印象笔记设离线包出差查阅【离线阅读】
最新韩小圈网页版登录入口_官网在线观看官方链接
快速CSGO开箱网站指南 CSGO开箱平台推荐
Golang如何处理RPC请求负载均衡_Golang RPC请求负载均衡策略与实践
Golang如何通过reflect获取匿名字段方法_Golang reflect匿名字段方法访问技巧
利用Bokeh CustomJS动态控制DataTable列可见性
c++如何使用Catch2编写单元测试_c++简洁易用的BDD风格测试框架
J*aScript井字棋(Tic-Tac-Toe)核心交互逻辑实现教程
处理Kafka消费者会话超时:深入理解消息处理语义与幂等性
Spring Boot嵌入式服务器与J*a EE:功能支持深度解析
c++如何使用Meson构建系统_c++比CMake更快的构建工具
Pandas DataFrame:高效添加条件计算列
sublime如何配置Python开发环境_将sublime打造成轻量级Python IDE
Pandas DataFrame 多条件优先级排序与排名
CSS Grid如何控制元素对齐_align-items与justify-items组合使用
Win11怎么开启卓越性能模式 Win11电源选项启用高性能释放硬件潜力【方法】
Odoo 16:在表单视图中基于当前记录动态修改Tree视图属性
2026年CSGO开箱网站推荐 CSGO开箱平台精选
J*aScript中高效清空DOM列表元素:解决for循环中断与任务管理问题
Go语言中Map存储的结构体如何调用指针方法:深入解析与实践
4399体育竞技小游戏_4399小游戏赛事入口
抖音DOU+怎么投最有效 抖音付费推广的ROI提升技巧
怎么在mac上运行html代码_mac运行html代码方法【指南】
J*aScript生成器_j*ascript异步迭代
Golang如何优化CPU绑定任务分配策略_Golang CPU任务分配优化实践
C++如何实现线程池_C++11手动实现一个简单的固定大小线程池


2025-11-13
浏览次数:次
返回列表
= model.Email.Split('@')[0];
if (model.Name.Contains(emailPrefix))
{
return new ValidationResult("用户名不能包含邮箱前缀");
}
}
return ValidationResult.Success;
}
}