在我的 ASP.NET Razor Page Project 中遇到了类似的问题。创建自定义 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() 方法中的创建和编辑页面模型中使用它,如下所示。
创建模型:
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 视图应该在表单中设置模型验证以捕获并显示错误。
IE,
<div class="text-danger" asp-validation-summary="ModelOnly"></div>
并低于针对该领域的验证。
<span asp-validation-for="Book.Name" class="text-danger"></span>