【发布时间】:2015-03-18 21:00:10
【问题描述】:
问题
我在应用程序的其他地方非常相似地使用以下代码,但它不起作用。我完全被难住了。
The ViewData item that has the key 'ShelfId' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'
这是在 post 方法期间抛出的。我的模型状态无效。
代码
模型
架子
public class Shelf
{
[Key]
public int ShelfId
[Display(Name = "Shelf Id")]
[Required]
public string ShelfName
public virtual List<Book> Books {get; set;}
}
图书
public class Book
{
public int BookId
[Required]
[StrengthLength(160, MinimumLength = 8)]
public string BookName
public int ShelfId
public Shelf shelf {get; set;}
}
控制器
// 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);
}
查看
@model AgentInventory.Models.Book
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Create Unit</title>
</head>
<body>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal well bs-component" style="margin-top:20px">
<h4>Unit</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
<div class="control-label col-md-2">Room</div>
<div class="col-md-10">
@Html.DropDownListFor(model => model.ShelfId, (SelectList)ViewBag.SelectedShelves, "All", new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.BookName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.BookName, "", new { @class = "text-danger" }
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
尝试
我试过了:
- 在创建视图中添加
@Html.HiddenFor(model=>model.ShelfId),但这不起作用。 - 我在 stackoverflow 上查看过类似的问题,但没有一个修复对我有用。 (IE - hiddenfor,不同种类的选择列表)
由于我是 MVC 框架的新手,我将不胜感激任何帮助。我不明白为什么这段代码适用于其他两种模型(建筑物和房间),但不适用于我目前的两种模型?有点奇怪。
PS - 有没有办法在不使用 viewbag 的情况下轻松做到这一点?
【问题讨论】:
-
@CodeCaster 当我这样做时,它会直接返回到 Create 视图而没有错误。我想我需要仔细看看无效状态模型的调试器。我怀疑那里有什么东西搞砸了,希望会暴露出来。
-
是的,因为当您返回视图时,
SelectList是null。返回视图时需要在POST方法中使用ViewBag.SelectedShelves = new SelectList(shelves, "ShelfId", "Name");。 -
什么意思,你得到了创建视图?这就是你应该得到的。如果
ModelState无效,它会返回视图以便用户更正错误。你期望发生什么 -
那么您的
Book模型显然还有其他属性,例如您未显示的CreatedBy。毫无疑问,其中一些具有验证属性,因此ModelState无效。您确实需要开始使用视图模型来表示您想要显示/编辑的内容。
标签: asp.net-mvc asp.net-core viewbag visual-studio-2015 asp.net-core-mvc