Asp.net mvc 具有键';谢尔菲德';类型为';System.Int32';但必须为'型;IEnumerable<;选择列表项>'; 问题
在我的应用程序中,我在其他地方非常类似地使用以下代码,但它不起作用。我完全被难住了Asp.net mvc 具有键';谢尔菲德';类型为';System.Int32';但必须为'型;IEnumerable<;选择列表项>'; 问题,asp.net-mvc,asp.net-core,viewbag,visual-studio-2015,asp.net-core-mvc,Asp.net Mvc,Asp.net Core,Viewbag,Visual Studio 2015,Asp.net Core Mvc,在我的应用程序中,我在其他地方非常类似地使用以下代码,但它不起作用。我完全被难住了 The ViewData item that has the key 'ShelfId' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>' 控制器 // GET: Units/Create public async Task<IActionResult> Create()
The ViewData item that has the key 'ShelfId' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'
控制器
// GET: Units/Create
public async Task<IActionResult> Create()
{
var shelves = await _db.Shelves.OrderBy(q => q.Name).ToListAsync();
ViewBag.SelectedShelves = new SelectList(shelves, "ShelfId", "Name");
return View();
}
// POST: Units/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Book book)
{
book.CreatedBy = User.Identity.GetUserName();
book.Created = DateTime.UtcNow;
book.UpdatedBy = User.Identity.GetUserName();
book.Updated = DateTime.UtcNow;
if (ModelState.IsValid)
{
db.Units.Add(unit);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(book);
}
//获取:单位/创建
公共异步任务创建()
{
var shelfs=await_db.shelfs.OrderBy(q=>q.Name.ToListAsync();
ViewBag.selectedshelfs=新的选择列表(shelfs,“ShelfId”,“Name”);
返回视图();
}
//职位:单位/创建
[HttpPost]
[ValidateAntiForgeryToken]
公共异步任务创建(书本)
{
book.CreatedBy=User.Identity.GetUserName();
book.Created=DateTime.UtcNow;
book.UpdatedBy=User.Identity.GetUserName();
book.Updated=DateTime.UtcNow;
if(ModelState.IsValid)
{
db.Units.Add(单位);
等待db.saveChangesSync();
返回操作(“索引”);
}
返回视图(书);
}
看法
@model AgentInventory.Models.Book
创建单元
@使用(Html.BeginForm())
{
@Html.AntiForgeryToken()
单位
@Html.ValidationSummary(true,“,new{@class=“text danger”})
房间
@DropDownListFor(model=>model.ShelfId,(SelectList)ViewBag.selectedshelfs,“全部”,新的{@class=“form control”})
@LabelFor(model=>model.Name,htmlAttributes:new{@class=“controllabel col-md-2”})
@EditorFor(model=>model.BookName,new{htmlAttributes=new{@class=“form control”}})
@Html.ValidationMessageFor(model=>model.BookName,“,new{@class=“text danger”}
}
@ActionLink(“返回列表”、“索引”)
尝试
我试过:
- 在创建视图中添加
,但这不起作用@Html.HiddenFor(model=>model.ShelfId)
- 我已经研究过stackoverflow上的类似问题,但没有一个修复对我有效
PS-有没有一种方法可以在不使用viewbag的情况下轻松执行此操作?错误的原因是,在返回视图的POST方法中,
viewbag.SelectedShelfs的值为空,因为您尚未设置它(正如您在get方法中所做的那样。我建议您在一个私有方法中重构它,该私有方法可以从get和POST方法调用
private void ConfigureViewModel(Book book)
{
var shelves = await _db.Shelves.OrderBy(q => q.Name).ToListAsync();
// Better to have a view model with a property for the SelectList
ViewBag.SelectedShelves = new SelectList(shelves, "ShelfId", "Name");
}
然后在控制器中
public async Task<IActionResult> Create()
{
// Always better to initialize a new object and pass to the view
Book model = new Book();
ConfigureViewModel(model)
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Book book)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(book)
return View(book);
}
// No point setting these if the model is invalid
book.CreatedBy = User.Identity.GetUserName();
book.Created = DateTime.UtcNow;
book.UpdatedBy = User.Identity.GetUserName();
book.Updated = DateTime.UtcNow;
// Save and redirect
db.Units.Add(unit);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
然后修改private方法,将SelectList
分配给视图模型(而不是ViewBag
),并在控制器方法中,将BookVM
的新实例传递给视图,然后发回
public async Task<IActionResult> Create(BookVM model)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model)
return View(model);
}
// Initialize a new Book and set the properties from the view model
}
public异步任务创建(BookVM模型)
{
如果(!ModelState.IsValid)
{
配置视图模型(模型)
返回视图(模型);
}
//初始化新书并从视图模型中设置属性
}
@CodeCaster当我这样做时,它会将我直接返回到创建视图,没有错误。我想我需要仔细查看无效状态模型的调试器。我怀疑那里出了什么问题,希望会暴露出来。是的,因为返回视图时,SelectList
是null
。您需要o使用ViewBag.selectedshelfs=新的选择列表(shelfs,“ShelfId”,“Name”)
在返回视图时在POST方法中。什么意思,您得到的是创建视图?这是您应该得到的。如果ModelState
无效,它将返回视图,以便用户可以更正错误。您希望发生什么呢书籍模型显然还有其他属性,例如CreatedBy您尚未显示的代码>。毫无疑问,其中一些具有验证属性,因此ModelState
无效。您确实需要开始使用视图模型来表示要显示/编辑的内容。此答案是一件艺术品。我无法充分支持此答案。此外,您对错误发生原因的解释也非常精彩。
private void ConfigureViewModel(Book book)
{
var shelves = await _db.Shelves.OrderBy(q => q.Name).ToListAsync();
// Better to have a view model with a property for the SelectList
ViewBag.SelectedShelves = new SelectList(shelves, "ShelfId", "Name");
}
public async Task<IActionResult> Create()
{
// Always better to initialize a new object and pass to the view
Book model = new Book();
ConfigureViewModel(model)
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Book book)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(book)
return View(book);
}
// No point setting these if the model is invalid
book.CreatedBy = User.Identity.GetUserName();
book.Created = DateTime.UtcNow;
book.UpdatedBy = User.Identity.GetUserName();
book.Updated = DateTime.UtcNow;
// Save and redirect
db.Units.Add(unit);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
public class BookVM
{
public int Id { get; set; }
[Required]
[StrengthLength(160, MinimumLength = 8)]
public string Name { get; set; }
public int SelectedShelf { get; set; }
public SelectList ShelfList { get; set; }
}
public async Task<IActionResult> Create(BookVM model)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model)
return View(model);
}
// Initialize a new Book and set the properties from the view model
}