如何在DisplayFor助手方法中按AuthorId显示作者姓名

时间:2019-06-28 20:47:01

标签: c# asp.net model-view-controller

在我的Book实体类中,我具有AuthorId导航属性。在Selectlist中用作dataValueField。

<!--language:lang-csharp-->
public class Book
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public double Price { get; set; }
        public int Stock { get; set; }
        public int AuthorId { get; set; }
        public  Author Author { get; set; }
        public virtual List<Review> Reviews { get; set; }

    } 

    ViewBag.AuthorId = new SelectList(db.Authors,“ Id”,“ Name”);

这将通过表单内的DropdownList帮助器按预期方式呈现。

            <div class="form-group m-b-40">
                    @Html.DropDownList("AuthorId", null, "", htmlAttributes: new { @class = "form-control p-0 input-value", id = "input6" })
                    <span class="bar"></span>
                    <div class="error">
                        <small class="error_form" id="authors_error_message"></small>
                        <div class="icon"></div>
                    </div>
                    <label for="input6">Authors</label>
                </div>

输出:

<!--language:lang-html-->
        <select class="form-control p-0 input-value" id="input6" name="AuthorId">
        <option value="1">George R.R. Martin</option>
        <option value="2">James Dashner</option>
        <option value="3">Culian Barns</option>
        </select>

我在局部视图中获得了Book对象,并使用DisplayFor助手将其显示在表中,但我希望将其显示为“名称而不是值”

<!--language:lang-html-->
@model Project.Entities.Book
<td>
    <p class="wrap-1">@Html.DisplayFor(b => b.AuthorId)</p>
</td>

如何做到?

更新

正如下面的评论所述,事实证明,当从数据库中获取数据时,我应该包括导航属性,因此,考虑到此action方法的结构,如何正确地进行导航?我可以通过以下代码简单地包含属性:

var mybook = db.Books.Where(b => b.Id == book.Id).Include(a => a.Author).Include(c => c.Category).FirstOrDefault();

但是,只有在检查ModelState的有效性为true并将书籍保存在数据库中之后,才能执行此操作。在进入ModelState is valid condition之前,我希望这样做,以便可以在将上下文保存到数据库之前检查上下文是否已被嵌套实体填充。怎么做?

<!--language:lang-csharp--> 
 [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;
            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);
                }
            }
         }

2 个答案:

答案 0 :(得分:1)

从数据库中获取数据时,您需要Include这样的嵌套实体:

context.Books.Where(b=> b.Any()).Include(a => a.Author);

答案 1 :(得分:0)

首先,您正在使用AuthorId,因此将显示该内容。如果需要作者姓名,则应该b.Author.Name

第二,将实体直接绑定到视图不是一个好习惯。您之间应该有一个ViewModel。使用实体填充ViewModel,并且在ViewModel中仅包含必需的属性/数据,而不是所有实体数据。另外,以适合您的用例的方式构造ViewModel以便在View中显示。将ViewModel绑定到视图,而不使用实体来显示数据。