.NET Core 数据验证(最全实战指南)

.NET Core 内置**强大的模型验证(Model Validation)**机制,基于 DataAnnotations 数据注解 + 自动验证,无需手写大量判断代码,是 API、MVC 项目的标准验证方案。

我给你整理最常用、最实用的用法,直接复制就能用!


一、最核心用法:DataAnnotations 注解(推荐)

直接在模型类 / DTO 上加特性,框架会自动验证,无需手动判断。

1. 常用验证特性(背会这 10 个就够用)

csharp 复制代码
// 必填
[Required(ErrorMessage = "用户名不能为空")]

// 字符串长度
[StringLength(50, MinimumLength = 2, ErrorMessage = "长度 2-50 位")]

// 范围(数字)
[Range(1, 120, ErrorMessage = "年龄必须在 1-120 之间")]

// 正则表达式(手机号、身份证等)
[RegularExpression(@"^1[3-9]\d{9}$", ErrorMessage = "手机号格式不正确")]

// 邮箱格式
[EmailAddress(ErrorMessage = "邮箱格式不正确")]

// 密码复杂度
[DataType(DataType.Password)]

// 比较两个字段(确认密码)
[Compare("Password", ErrorMessage = "两次密码不一致")]

// 电话号码
[Phone(ErrorMessage = "电话号码格式错误")]

// 最大/最小值
[MaxLength(100)]
[MinLength(6)]

// 自定义错误消息
[Required(ErrorMessage = "请输入姓名")]

二、完整实战示例(DTO + 自动验证)

1. 定义 DTO(带验证)

csharp 复制代码
using System.ComponentModel.DataAnnotations;

namespace YourProject.DTOs
{
    public class CreateUserDto
    {
        [Required(ErrorMessage = "用户名不能为空")]
        [StringLength(20, MinimumLength = 2, ErrorMessage = "用户名长度 2-20 位")]
        public string UserName { get; set; }

        [Required(ErrorMessage = "密码不能为空")]
        [MinLength(6, ErrorMessage = "密码至少 6 位")]
        public string Password { get; set; }

        [Required(ErrorMessage = "确认密码不能为空")]
        [Compare(nameof(Password), ErrorMessage = "两次密码不一致")]
        public string ConfirmPassword { get; set; }

        [EmailAddress(ErrorMessage = "邮箱格式不正确")]
        public string Email { get; set; }

        [RegularExpression(@"^1[3-9]\d{9}$", ErrorMessage = "手机号格式错误")]
        public string Phone { get; set; }

        [Range(1, 120, ErrorMessage = "年龄必须在 1-120 之间")]
        public int Age { get; set; }
    }
}

三、API 中自动使用验证(无需手写判断)

1. 控制器写法(.NET Core 自动验证)

csharp 复制代码
using Microsoft.AspNetCore.Mvc;
using YourProject.DTOs;

[Route("api/[controller]")]
[ApiController]  // 关键:加了这个,框架会自动验证模型
public class UserController : ControllerBase
{
    [HttpPost("create")]
    public IActionResult Create(CreateUserDto dto)
    {
        // 重点:加了 [ApiController],如果验证失败,框架会自动返回 400 错误!
        // 这里直接写业务逻辑即可

        return Ok("创建成功");
    }
}

2. 自动返回的错误格式(前端直接用)

json 复制代码
{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "UserName": ["用户名不能为空"],
    "Phone": ["手机号格式错误"],
    "Age": ["年龄必须在 1-120 之间"]
  }
}

四、手动获取验证结果(兼容老项目)

如果没加 [ApiController],可以手动判断:

csharp 复制代码
[HttpPost("create")]
public IActionResult Create(CreateUserDto dto)
{
    // 手动判断验证是否通过
    if (!ModelState.IsValid)
    {
        // 返回验证错误
        return BadRequest(ModelState);
    }

    return Ok("创建成功");
}

五、自定义验证(满足特殊业务规则)

如果内置注解不够用,可以自定义验证特性

示例:验证"用户名不能包含 admin"

csharp 复制代码
using System.ComponentModel.DataAnnotations;

public class NoAdminAttribute : ValidationAttribute
{
    protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
    {
        var userName = value?.ToString();
        
        if (userName != null && userName.Contains("admin"))
        {
            return new ValidationResult("用户名不能包含 admin");
        }

        return ValidationResult.Success;
    }
}

使用:

csharp 复制代码
[NoAdmin]  // 自定义验证
public string UserName { get; set; }

六、全局统一验证返回格式(企业级)

默认的 400 返回格式太丑,我们可以统一成前端友好格式

Program.cs 中配置:

csharp 复制代码
builder.Services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
    {
        // 自定义验证失败返回结果
        options.InvalidModelStateResponseFactory = context =>
        {
            // 提取所有错误信息
            var errors = context.ModelState
                .Where(e => e.Value.Errors.Count > 0)
                .ToDictionary(
                    k => k.Key,
                    v => v.Value.Errors.Select(e => e.ErrorMessage).ToArray()
                );

            // 统一返回格式
            var result = new
            {
                Code = 400,
                Message = "参数验证失败",
                Errors = errors
            };

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

返回效果:

json 复制代码
{
  "Code": 400,
  "Message": "参数验证失败",
  "Errors": {
    "UserName": ["用户名不能为空"],
    "Phone": ["手机号格式错误"]
  }
}

七、服务层(Service)验证

如果想在业务层做验证,可以手动调用:

csharp 复制代码
using System.ComponentModel.DataAnnotations;

public class UserService
{
    public void CreateUser(CreateUserDto dto)
    {
        // 手动验证
        var validationContext = new ValidationContext(dto);
        var validationResults = new List<ValidationResult>();

        bool isValid = Validator.TryValidateObject(dto, validationContext, validationResults, true);

        if (!isValid)
        {
            // 处理错误
            throw new ArgumentException("参数错误");
        }
    }
}

核心总结(必看)

  1. 最简单 :给 DTO 加 [Required][EmailAddress] 等注解
  2. 最方便 :控制器加 [ApiController],自动验证、自动返回错误
  3. 最规范:全局配置统一错误返回格式
  4. 扩展:内置不够用 → 写自定义验证特性

总结:.NET Core 验证 = 数据注解 + 自动校验,零冗余代码!

相关推荐
爱勇宝8 小时前
第 1 章:别把“需求文档”当成真正的需求
前端·后端·程序员
IT_陈寒12 小时前
闭包陷阱让我加了两天班,JavaScript你真行
前端·人工智能·后端
易协同低代码13 小时前
通达OA核心类库TD类深度解析
后端
Gopher_HBo13 小时前
Go语言学习笔记(十八)Gin处理Session
后端
谭光志14 小时前
工具塞满上下文窗口怎么办?深度拆解 AI Agent Tool Search 按需加载实现原理
前端·后端·ai编程
她说..14 小时前
Java 默认值设置方式
java·开发语言·后端·springboot
foggyprojects14 小时前
从0开始,一句话启动AI DataAgent
后端·数据分析·ai编程
郡杰14 小时前
一些基础和问题解决
后端
随心(cracker)15 小时前
BeaverX Admin:一套真正能跑起来的开源管理后台
vue·.net·管理后台
陈随易15 小时前
前端项目部署只要30秒
前端·后端·程序员