ASP.NET MVC3:DropdownList中的对象在控制器中为空

问题描述:

我为BookShop创建了一个示例MVC3应用程序。我有一个创建行动。在创建操作中,用户输入书名,作者姓名并选择流派名称。它工作没有错误。但在控制器中,我没有得到所选的流派名称( - 流派对象为空)。我们如何纠正它?ASP.NET MVC3:DropdownList中的对象在控制器中为空

注意:当我编写@Html.DropDownList("GenreId", String.Empty) ASP.NET MVC中内置的模型绑定功能将尝试使用表单输入来填充该类型的对象。例如。它会尝试设置书对象的GenreId值。但Book不包含属性GenreId。但是,下拉菜单可以通过从ViewBag中读取所需的值来显示值。

CODE

@model MyBookShopApp.Book 

@{ 
ViewBag.Title = "Create"; 
} 

<h2>Create</h2> 

@using (Html.BeginForm()) { 

@Html.ValidationSummary(true) 

<fieldset> 

    <legend>BOOK</legend> 


    <div > 
     @Html.LabelFor(model => model.Title) :~: @Html.EditorFor(model => model.Title) 
    </div> 


    <div > 
     @Html.LabelFor(model => model.Artist.Name) :*: @Html.EditorFor(model => model.Artist.Name) 
    </div> 


    <div > 
     @Html.LabelFor(model => model.GenreEntity.Name, "The Genre") :: @Html.DropDownList("GenreId", String.Empty) 
    </div> 


    <p> 
     <input type="submit" value="Create" /> 
    </p> 

</fieldset> 
} 

<div> 
@Html.ActionLink("Back to List", "Index") 
</div> 

CONTROLLER

namespace MyBookShopApp.Controllers 
{ 
public class StoreManagerController : Controller 
{ 

    List<GenreEntity> listOfGenres = new List<GenreEntity>() 
            { 
             new GenreEntity { Name = "Fiction", GenreId = 1 }, 
             new GenreEntity { Name = "Science", GenreId = 2 }, 
             new GenreEntity { Name = "Religious", GenreId = 3 }, 
            }; 

    List<Book> bookList = new List<Book>() 
          { 
          new Book 
          { 
           BookId = 1,Title = "Book1", 
           GenreEntity = new GenreEntity { Name = "Fiction", GenreId = 1 }, 
           Artist = new Artist { ArtistId = 1, Name = "Dinesh" } 
          }, 
          new Book 
          { 
           BookId = 2,Title = "Book2", 
           GenreEntity = new GenreEntity { Name = "Science", GenreId = 2 }, 
           Artist = new Artist { ArtistId = 1, Name = "Lijo" } 
          }, 
          new Book 
          { 
           BookId = 3,Title = "Book3", 
           GenreEntity = new GenreEntity { Name = "Religious", GenreId = 3 }, 
           Artist = new Artist { ArtistId = 1, Name = "Santhosh" } 
          } 

          }; 





    #region CREATE 



    // GET: 
    public ActionResult Create() 
    { 
        ViewBag.GenreId = new SelectList(listOfGenres, "GenreId", "Name"); 
     return View(); 
    } 

    // POST: 
    [HttpPost] 
    public ActionResult Create(Book theBook) 
    { 
     if (ModelState.IsValid) 
     { 
      //Save the book in DB first and then redirectToAction. 
      return RedirectToAction("Index"); 
     } 

     return View(theBook); 
    } 

    #endregion 


} 
} 

Book类

public class Book 
{ 
    public int BookId { get; set; } 
    public string Title { get; set; } 
    public GenreEntity GenreEntity { get; set; } 
    public Artist Artist { get; set; } 

} 

GenreEntity

public class GenreEntity 
{ 
    public string Name { get; set; } 
    public int GenreId { get; set; } 
} 

艺术家类

public class Artist 
{ 
    public int ArtistId { get; set; } 
    public string Name { get; set; } 
} 

REFERENCE

  1. dropdown in mvc3 edit form

  2. How to use a Html.DropDownList in a strongly-typed view for a model containing a nullable enum property?

  3. MVC3 HTML helper doesn't update DropdownListFor on Submit the form

  4. on select change event - Html.DropDownListFor

  5. MVC3 @Html.DropDownListFor not populating selected item

@Html.DropDownList("GenreId", String.Empty)用名称GenreId创建一个SELECT。但是MVC3期望名称GenreEntity.Name绑定到Book。

简单的解决办法是修改public ActionResult Create(Book theBook) public ActionResult Create(Book theBook, string genreId)接收访问内容被调回

或者

@Html.LabelFor(model => model.GenreEntity.GenreId, "The Genre") 
@Html.DropDownListFor(model => model.GenreEntity.GenreId, (SelectList)ViewBag.GenreId, String.Empty) 

记得设置你的ViewBag的HttpPost Create方法里面也genreId。

编辑 从BOOKID更正的属性名称GenreId

+0

我更愿意将该值添加到书对象的genreEntity。我们如何实现这一目标?注意:“GenreId”来自ViewBag。 – Lijo 2012-02-18 10:03:05

+0

谢谢。您的备选建议有效。但GenreEntity对象仅具有GenreId值。 GenreEntity对象的“名称”为空。任何方式来填补这个价值呢?我们是否使用适当的方法/模式来获得价值? – Lijo 2012-02-18 10:46:13

+0

我会做的是使用GenreId检索服务器上的Name等的值(例如,通过DB查询)。如果你想坚持一切,你最终会得到WebForms和MVC3试图避免的大ViewState。 – 2012-02-18 11:04:04

你的下拉试图将其值赋给一个名为Book.GenreId属性。您的GenreEntity类拥有GenreId属性,而不是Book(基于上面粘贴的代码)。

您可以通过修改下拉到这个纠正这一点,

@Html.DropDownList("GenreEntity.GenreId", String.Empty) 

这将告诉MVC的下降值分配到Book.GenreEntity.GenreId

+0

感谢。但是我得到的例外是:“没有ViewData类型的项目'IEnumerable '有'GenreEntity.GenreId'键。” – Lijo 2012-02-18 09:44:54

+0

本书不包含属性GenreId – 2012-02-18 09:44:54