.NET 6 Razor Page更新模型时,如何保留唯一属性RollNo并通过验证?
解决Razor Page更新模型时唯一属性重复验证问题
针对你遇到的更新时RollNo未修改却触发唯一值验证错误的问题,提供以下几种可行方案:
方案1:自定义唯一验证属性,排除当前实体
替换原来的唯一验证属性,新增一个能识别当前实体的自定义验证逻辑,只检查其他实体是否存在重复的RollNo:
public class UniqueRollNoAttribute : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var dbContext = (YourDbContextType)validationContext.GetService(typeof(YourDbContextType)); var currentClass = (Class)validationContext.ObjectInstance; // 仅当存在其他实体的RollNo与当前值重复时,才返回错误 var isDuplicate = dbContext.Classes.Any(c => c.RollNo == value.ToString() && c.Id != currentClass.Id); return isDuplicate ? new ValidationResult("Roll number already exists") : ValidationResult.Success; } }
然后在Class模型的RollNo属性上应用这个自定义属性:
public class Class { public int Id { get; set; } [UniqueRollNo] public string RollNo { get; set; } // 其他属性... }
方案2:在更新方法中手动移除无关验证错误
如果不想修改验证属性,可在页面的OnPostAsync方法中,先对比现有实体的RollNo与提交的RollNo,确认未修改后,移除对应的ModelState错误:
public async Task<IActionResult> OnPostAsync(int id) { var existingClass = await _context.Classes.FindAsync(id); if (existingClass == null) return NotFound(); // 若RollNo未发生变化,移除该属性的验证错误 if (existingClass.RollNo == Class.RollNo) { ModelState.Remove("Class.RollNo"); } if (!ModelState.IsValid) return Page(); // 更新实体属性并保存 _context.Entry(existingClass).CurrentValues.SetValues(Class); try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { // 处理并发冲突逻辑 } return RedirectToPage("./Index"); }
方案3:使用EF Core部分更新,避免全量验证
不直接替换整个实体,只更新需要修改的属性,这样既不会触发不必要的验证,也能提升性能:
public async Task<IActionResult> OnPostAsync(int id) { var existingClass = await _context.Classes.FindAsync(id); if (existingClass == null) return NotFound(); // 仅更新需要修改的属性(示例为Name和Grade) existingClass.Name = Class.Name; existingClass.Grade = Class.Grade; // 其他需要更新的属性... // 标记修改的属性为已变更 _context.Entry(existingClass).Property(c => c.Name).IsModified = true; _context.Entry(existingClass).Property(c => c.Grade).IsModified = true; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { // 处理并发冲突逻辑 } return RedirectToPage("./Index"); }
内容的提问来源于stack exchange,提问作者Neerajan Rai
相关产品推荐
相关产品推荐

