在我的 ASP.NET Razor 页面项目中遇到了类似的问题。创建自定义 UniqueDataAttribute 不起作用,因为在编辑时,如果您不更改唯一字段,它将引发错误。
我需要唯一的书名。我就是这样解决的:
- 我通过 EF Core 迁移向数据库中的字段添加了唯一约束。在 ApplicationDbContext 类中添加以下内容,然后运行迁移。
代码:
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Book>()
.HasIndex(u => u.Name)
.IsUnique();
}
- 接下来,创建了如下的辅助/扩展方法。
代码:
// Validate uniqueness of Name field in database.
// If validation is done on existing record, pass the id of the record.
// Else, if validating new record Name, then id is set to dummy key integer -1
public static bool UniqueNameInDb(this string data, ApplicationDbContext db, int id = -1)
{
var duplicateData = from o in db.Book
where o.Name == data && o.Id != id
select o;
if(duplicateData.Any())
{
return false;
}
return true;
}
}
- 然后在 OnPost() 方法的 Create and Edit page model 中使用如下。
创建模型:
public async Task<IActionResult> OnPost()
{
if(ModelState.IsValid)
{
if (!Book.Name.UniqueNameInDb(_db)) //<--Uniqueness validation
{
ModelState.AddModelError("Book.Name", "Name already exist"); //<-- Add error to the ModelState, that would be displayed in view.
return Page();
}
await _db.Book.AddAsync(Book);
await _db.SaveChangesAsync();
return RedirectToPage("Index");
}
else
{
return Page();
}
}
编辑模型:
public async Task<IActionResult> OnPost()
{
if(ModelState.IsValid)
{
var bookFromDb = await _db.Book.FindAsync(Book.Id);
if (!Book.Name.UniqueNameInDb(_db, Book.Id)) //<--Uniqueness validation
{
ModelState.AddModelError("Book.Name", "Name already exist"); //<-- Add error to the ModelState, that would be displayed in view.
return Page();
}
bookFromDb.Name = Book.Name;
bookFromDb.Author = Book.Author;
await _db.SaveChangesAsync();
return RedirectToPage("Index");
}
return Page();
}
PS:您的 Razor 视图应该在表单中设置模型验证以捕获并显示错误。
即
<div class="text-danger" asp-validation-summary="ModelOnly"></div>
及以下针对该字段的验证。
<span asp-validation-for="Book.Name" class="text-danger"></span>