如何在DisplayFor辅助方法中通过AuthorId显示作者名及加载导航属性
解决Book实体显示作者名称及预加载导航属性的问题
问题1:在DisplayFor中显示作者名称而非AuthorId值
要显示作者名称,你需要直接访问Book的Author导航属性的Name字段,而不是AuthorId。但前提是你的Book对象已经正确加载了Author导航属性。
修改你的局部视图代码:
@model Project.Entities.Book <td> <p class="wrap-1">@Html.DisplayFor(b => b.Author?.Name)</p> </td>
这里用了?.空条件运算符,防止Author为null时出现空引用异常。如果你的项目不支持C# 6及以上版本,也可以用判断语句做兼容:
<td> <p class="wrap-1">@(Model.Author != null ? Model.Author.Name : "Unknown Author")</p> </td>
问题2:在ModelState验证前加载导航属性
你当前的Post_AddBook方法里,只有在ModelState.IsValid为true时才会处理书籍保存,但验证不通过时返回的book对象并没有加载Author和Category导航属性,导致视图无法显示名称。
你需要在ModelState验证之前,手动从数据库加载对应的Author和Category并赋值给传入的book对象,这样不管验证是否通过,视图都能获取到导航属性的数据。
修改后的Action代码如下:
[HttpPost] public ActionResult Post_AddBook ([Bind(Include = "Id,Name,Description,Price,Stock,DateAdded,ISBN,IsApproved,AuthorId,CategoryId")] Book book, HttpPostedFileBase photo) { book.DateAdded = DateTime.Now; // 先加载导航属性,不管ModelState是否有效 if (book.AuthorId > 0) { book.Author = db.Authors.Find(book.AuthorId); // 如果找不到对应作者,添加ModelState错误提示 if (book.Author == null) { ModelState.AddModelError("AuthorId", "Selected author does not exist."); } } if (book.CategoryId > 0) { book.Category = db.Categories.Find(book.CategoryId); if (book.Category == null) { ModelState.AddModelError("CategoryId", "Selected category does not exist."); } } if (ModelState.IsValid) { if (photo != null && photo.ContentLength > 0 && (Path.GetExtension(photo.FileName) == ".jpg")) { db.Books.Add(book); db.SaveChanges(); var path = Path.Combine(Server.MapPath("/Uploads/img/"), book.Id + ".jpg"); photo.SaveAs(path); return PartialView(book); } // 如果照片不符合要求,添加错误提示 ModelState.AddModelError("", "Please upload a valid JPG image."); } // 验证不通过时返回视图,此时book已经加载了导航属性 return PartialView(book); }
说明:
- 我们在验证前通过
Find方法根据ID获取Author和Category实体,直接赋值给book的导航属性。 - 增加了对无效ID的判断,避免出现不存在的作者/分类,同时给用户明确的错误反馈。
- 这样即使ModelState验证失败,返回的
book对象也包含了完整的导航属性数据,视图就能正常显示作者名称了。
内容的提问来源于stack exchange,提问作者Cavid
相关产品推荐
相关产品推荐

