【问题标题】:The model item passed into the ViewDataDictionary is of type '*',but this ViewDataDictionary instance requires a model item of type '..IEnumerable[*]'传递到 ViewDataDictionary 的模型项的类型为“*”,但此 ViewDataDictionary 实例需要“..IEnumerable[*]”类型的模型项
【发布时间】:2020-10-20 15:02:17
【问题描述】:

我查看并实施了类似主题的解决方案,但不幸的是他们没有为我提供解决方案。

错误信息:

InvalidOperationException:传递到 ViewDataDictionary 的模型项属于“CMS.Models.Page”类型,但此 ViewDataDictionary 实例需要“System.Collections.Generic.IEnumerable`1[CMS.Models.Page] 类型的模型项'。

我正在开发一个简单的 cms。我的目标是在列出我的页面后对它们进行一些更改。

一段时间以来,我一直在尝试修复该错误,但我无法从我应用的解决方案中获得任何结果。我的猜测是这里的模型结构的数据通信问题。在我的代码下方:

家庭控制器:

    public class HomeController : Controller
{

    private readonly ApplicationDbContext _dbContext;

    public HomeController(ApplicationDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public IActionResult Index()
    {
        var page = _dbContext.Pages.FirstOrDefault(x => x.Title == "Home");
        return View(page);
    }


    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }
}

管理员控制器:

public class AdminController : Controller
{
    private readonly ApplicationDbContext _context;

    public AdminController(ApplicationDbContext context)
    {
        _context = context;
    }

    // GET: Pages
    public async Task<IActionResult> Index()
    {
        return View(await _context.Pages.ToListAsync());
    }

    public async Task<IActionResult> EditPage(string title)
    {
        // SELECT * FROM Pages WHERE Title = {title}
        var page = await _context.Pages.FirstOrDefaultAsync(x => x.Title == title);

        if (page == null)
        {
            page = new Page();
            page.Title = title;

            _context.Pages.Add(page);
            _context.SaveChanges();
        }
        return View(page);
    }

    // GET: Pages/Details/5
    public async Task<IActionResult> Details(int? id)
    {
        if (id == null)
        {
            return NotFound();
        }

        var page = await _context.Pages
            .FirstOrDefaultAsync(m => m.ID == id);
        if (page == null)
        {
            return NotFound();
        }

        return View(page);
    }

    // GET: Pages/Create
    public IActionResult Create()
    {
        return View();
    }

    // POST: Pages/Create
    // To protect from overposting attacks, enable the specific properties you want to bind to, for 
    // more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create([Bind("ID,Title,Content,Section")] Page page)
    {
        if (ModelState.IsValid)
        {
            _context.Add(page);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(page);
    }

    // GET: Pages/Edit/5
    public async Task<IActionResult> Edit(int? id)
    {
        if (id == null)
        {
            return NotFound();
        }

        var page = await _context.Pages.FindAsync(id);
        if (page == null)
        {
            return NotFound();
        }
        return View(page);
    }

    // POST: Pages/Edit/5
    // To protect from overposting attacks, enable the specific properties you want to bind to, for 
    // more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(int id, [Bind("ID,Title,Content,Section")] Page page)
    {
        if (id != page.ID)
        {
            return NotFound();
        }

        if (ModelState.IsValid)
        {
            try
            {
                _context.Update(page);
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!PageExists(page.ID))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }
            return RedirectToAction(nameof(Index));
        }
        return View(page);
    }

    // GET: Pages/Delete/5
    public async Task<IActionResult> Delete(int? id)
    {
        if (id == null)
        {
            return NotFound();
        }

        var page = await _context.Pages
            .FirstOrDefaultAsync(m => m.ID == id);
        if (page == null)
        {
            return NotFound();
        }

        return View(page);
    }

    // POST: Pages/Delete/5
    [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> DeleteConfirmed(int id)
    {
        var page = await _context.Pages.FindAsync(id);
        _context.Pages.Remove(page);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }

    private bool PageExists(int id)
    {
        return _context.Pages.Any(e => e.ID == id);
    }
}

我无法查看的页面 => EditPage:

@model IEnumerable<piktusCMS.Models.Page>

@{
    ViewData["Title"] = "Edit Page";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Index</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Content)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Section)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Content)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Section)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.ID">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

页面模型:

    public class Page
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    public string Title { get; set; }

    public string Content { get; set; }

    public string Section { get; set; }
}

数据库上下文:

    public class ApplicationDbContext : IdentityDbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    public DbSet<Page> Pages { get; set; }
}

提前感谢您的解决方案和建议

【问题讨论】:

  • 错误很明显。您将单个 CMS.Models.Page 对象传递给您的 EditPage 视图,而您的视图需要 IEnumerable&lt;CMS.Models.Page&gt;
  • 错误很明显 - 您正在尝试传递单个项目来查看需要收集的项目。要么更改视图以使用单个项目,要么从控制器返回集合。
  • 我解决了,谢谢大家。正如你在EditPage 行动中所说的那样,我把它当作一个清单。我没注意到return(page)。我更新为await _context.Pages.ToListAsync()
  • 思考;并回顾您的最后评论和受答案启发的更改 - lbracadabra - 如果您不需要它,请不要查询整个列表。如果您不想更改视图中的@model,只需执行return View(new [] {page})。当您有理由偏离提供的,接受答案时,您应该提出偏离该答案的考虑和推理(特别是如果该答案忽略了解决异常的方法不止一种但与您的情况相关) .改进问题和答案是一个迭代过程。

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


【解决方案1】:

您在 EditPage 中的模型是 IEnumerable&lt;piktusCMS.Models.Page&gt; 类型,但您从 EditPage 操作发送 piktusCMS.Models.Page 类型模型。您只需要在视图页面中更改您的模型。从这个@model IEnumerable&lt;piktusCMS.Models.Page&gt;到这个@model piktusCMS.Models.Page

【讨论】:

  • 这是一个很好的答案,解决了此类问题的隐含“为什么”和“如何”问题陈述。 (即“为什么会发生这种异常?”和“我该如何解决它?”)但是,有不止一种“如何”解决它的方法(在 OP 最近对他的问题的评论中明确了),以及你的答案承认这一点后可以改进。也就是说,不是“您只需要更改...”,而是“解决此 InvalidOperationException 的一种方法是更改​​...”。列出解决此问题的所有可能方法可能是不可取的,但承认其他方法是不可取的。
猜你喜欢
  • 1970-01-01
  • 2020-10-03
  • 2022-01-27
  • 2018-12-25
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
  • 2022-06-27
相关资源
最近更新 更多