Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 具有键';谢尔菲德';类型为';System.Int32';但必须为'型;IEnumerable<;选择列表项>'; 问题_Asp.net Mvc_Asp.net Core_Viewbag_Visual Studio 2015_Asp.net Core Mvc - Fatal编程技术网

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上的类似问题,但没有一个修复对我有效
由于我是MVC框架的新手,如果能得到任何帮助,我将不胜感激。我不明白为什么这段代码适用于另外两种模型(建筑模型和房间模型),但不适用于我目前的两种模型?这很奇怪


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
}