.NET5不使用EF时如何通过数据库表值实现输入模型验证
.NET5 不使用EF框架实现数据库联动参数校验的方案
完全不需要依赖EF框架,直接通过原生ADO.NET或者轻量ORM(如Dapper)就能实现,以下是两种常用实现方式:
方式1:自定义校验特性(推荐,适配ASP.NET Core原生校验体系)
这种方式可以和ASP.NET Core自带的模型校验逻辑无缝集成,请求进入控制器前会自动触发校验,校验失败直接返回标准化的400错误,无需手动编写调用逻辑。
实现步骤
- 首先安装必要依赖包:
Microsoft.Data.SqlClient(.NET5官方原生数据库操作包,无需依赖EF) - 自定义校验特性类:
using System.ComponentModel.DataAnnotations; using Microsoft.Data.SqlClient; /// <summary> /// 合法状态校验特性 /// </summary> public class ValidStatusAttribute : ValidationAttribute { // 实际项目中建议通过IConfiguration读取配置中的连接字符串,这里做演示示例 private readonly string _dbConnString = "你的数据库连接字符串"; protected override ValidationResult IsValid(object value, ValidationContext validationContext) { // 空值如果需要必填校验可单独搭配[Required]特性使用,本特性仅校验非空值的合法性 if (value == null) return ValidationResult.Success; var inputStatus = value.ToString(); // 原生ADO.NET查询Statuses表匹配状态值 var statusIsValid = false; using (var conn = new SqlConnection(_dbConnString)) { conn.Open(); var command = new SqlCommand("SELECT COUNT(1) FROM Statuses WHERE StatusValue = @InputStatus", conn); command.Parameters.AddWithValue("@InputStatus", inputStatus); var matchCount = (int)command.ExecuteScalar(); statusIsValid = matchCount > 0; } if (statusIsValid) return ValidationResult.Success; // 校验不通过返回指定错误信息 return new ValidationResult("Invalid Status"); } }
- 给输入模型的对应属性加校验特性:
public class Search { public string Name { get; set; } [ValidStatus] public string CurrentStatus { get; set; } }
效果
如果你的控制器添加了[ApiController]特性,ASP.NET Core会自动执行模型校验,当CurrentStatus值不在Statuses表的合法范围内时,会直接返回携带Invalid Status错误信息的400响应,无需手动判断ModelState.IsValid。
方式2:手动校验(适合非Web场景、自定义校验时机的需求)
如果不需要和框架自动校验体系集成,也可以在业务代码中直接编写校验逻辑:
using Microsoft.Data.SqlClient; using System.ComponentModel.DataAnnotations; public void ValidateSearchModel(Search inputModel) { if (string.IsNullOrWhiteSpace(inputModel.CurrentStatus)) { throw new ArgumentNullException(nameof(inputModel.CurrentStatus)); } using (var conn = new SqlConnection("你的数据库连接字符串")) { conn.Open(); var command = new SqlCommand("SELECT COUNT(1) FROM Statuses WHERE StatusValue = @InputStatus", conn); command.Parameters.AddWithValue("@InputStatus", inputModel.CurrentStatus); var matchCount = (int)command.ExecuteScalar(); if (matchCount <= 0) { throw new ValidationException("Invalid Status"); } } }
性能优化建议
如果Statuses表的合法状态值不会频繁变更,建议增加缓存减少数据库查询次数:
- 使用
IMemoryCache将所有合法状态值缓存,过期时间可根据业务调整为1-24小时 - 校验时直接从缓存读取合法值列表比对,缓存过期后再重新查询数据库更新缓存
内容的提问来源于stack exchange,提问作者DevSay
相关产品推荐
相关产品推荐

