ASP.NET 6创建时唯一列验证正常,更新时出现验证问题
问题解决:编辑时未修改名称却触发唯一验证错误
问题原因
当前的UniqueNameValidationAttribute验证逻辑会检查数据库中所有记录的Name字段是否重复。编辑操作时,当前被修改的记录本身就存在于数据库中,因此即使未修改Name,验证逻辑也会判定“名称已存在”,触发错误提示。
解决方案
修改验证特性,在编辑场景下排除当前实体的主键(Id),仅检查其他记录是否存在重复的Name:
1. 更新自定义验证特性代码
public class UniqueNameValidationAttribute : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var context = (ApplicationDbContext)validationContext.GetService(typeof(ApplicationDbContext)); // 获取当前验证的模型实例 var model = validationContext.ObjectInstance as RecipeTableModel; if (model == null || value == null) { return new ValidationResult("无效的输入"); } string name = value.ToString().Trim(); // 判断是创建(Id为默认值)还是编辑操作 bool isCreating = model.Id == 0; bool exists; if (isCreating) { // 创建时:检查是否有任何记录使用该名称 exists = context.Recipes.Any(a => a.Name == name); } else { // 编辑时:排除当前Id的记录,检查其他记录是否使用该名称 exists = context.Recipes.Any(a => a.Name == name && a.Id != model.Id); } return exists ? new ValidationResult("Ezzel a névvel már létre van hozva recept!") : ValidationResult.Success; } }
2. 关键逻辑说明
- 通过
validationContext.ObjectInstance获取当前提交的模型对象,从中提取主键Id。 - 创建场景:直接检查数据库中是否已有相同
Name的记录。 - 编辑场景:添加
a.Id != model.Id的条件,排除当前正在编辑的记录,仅验证其他记录是否存在名称冲突。
3. 额外注意事项
- 确保
RecipeTableModel包含Id属性(对应数据表的主键)。 - 如果主键类型不是
int(例如Guid),需要调整isCreating的判断逻辑,比如model.Id == default(Guid)。 - 对
value做空值和Trim处理,避免因空格导致的误判。
验证效果
修改后:
- 创建新数据时,若
Name重复仍会正常弹出错误提示。 - 编辑数据时,未修改
Name不会触发错误;若修改后的Name与其他记录重复,才会弹出错误提示。
内容的提问来源于stack exchange,提问作者Sandor.Oros
相关产品推荐
相关产品推荐

