我一直在项目中的外键问题上苦苦挣扎,但为了明确我的观点,我将为您提供 ASP.NET 中关系问题的官方教程。
我在this页面创建了这两个模型。
// Principal (parent)
public class Blog
{
public int Id { get; set; }
public ICollection<Post> Posts { get; } = new List<Post>(); // Collection navigation containing dependents
}
// Dependent (child)
public class Post
{
public int Id { get; set; }
public int BlogId { get; set; } // Required foreign key property
public Blog Blog { get; set; } = null!; // Required reference navigation to principal
}
他们是我们的模特。在 Models 文件夹中创建这些模型后,我创建了它们相应的控制器。然后,我将其添加到数据文件夹中的上下文脚本中:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasMany(e => e.Posts)
.WithOne(e => e.Blog)
.HasForeignKey(e => e.BlogId)
.IsRequired();
}
最后,我输入了 add-migration 和 update-database,一切正常。然后我在/Blogs/Create 中创建了一个博客。就成功完成了。但是当我尝试添加新帖子时,我什么也没有得到,页面只是重新加载,什么也没做。我在 PostsController 中的 create 函数中添加了一些断点,发现 ModelState 无效。
\[HttpPost\]
\[ValidateAntiForgeryToken\]
public async Task\<IActionResult\> Create(\[Bind("Id,BlogId")\] Post post)
{
if (ModelState.IsValid)
{
_context.Add(post);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["BlogId"] = new SelectList(_context.Set<Blog>(), "Id", "Id", post.BlogId);
return View(post);
}
ModelState 仍然无效。这是有道理的,因为我们没有将任何内容作为 Create.cshtml 中的参数推送到该函数。但我不明白应该如何处理这个问题。 我正在使用.Net 8。
当我删除 ModelState 检查时,没有出现错误。但我不知道这是否是一个可靠的解决方案。
正如您所看到的,默认的 asp.net core MVC 脚手架模板中没有按照设计生成导航属性,这使得 ModelState 无效。
您可以修改您的 Post 模型以保留 ModelState 验证:
public class Post
{
public int Id { get; set; }
public int BlogId { get; set; } // Required foreign key property
[Required(ErrorMessage = "The Blog is required.")]
public Blog Blog { get; set; } = new Blog(); // Required reference navigation to principal
}
通过这种方式,您可以使其不可为空并保持模型状态验证。