I just can't understand I tried everything I could so I hope you guys can help me. Error message :
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1[BookStore1.Models.Book]', but this ViewDataDictionary instance requires a model item of type 'BookStore1.Models.Account'.
That's like an online book-store and I was trying to make an action with which you can display all books in the database and edit them as an admin. That's my book model:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace BookStore1.Models
{
public class Book
{
[Key]
public int Id { get; set; }
[Required]
public string? Name { get; set; }
[Required]
public string? Author { get; set; } = "Unknown";
[Required]
public int Price { get; set; }
[NotMapped]
public IFormFile? Image { set; get; }
}
}
that's my admin controller:
using BookStore1.Data;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using BookStore1.Models;
namespace BookStore1.Controllers
{
[Authorize(Policy = "HasToBeAdmin")]
public class AdminController : Controller
{
private readonly AppDataContext _database;
private readonly IWebHostEnvironment _webHostEnvironment;
public AdminController(AppDataContext database, IWebHostEnvironment webHostEnvironment)
{
_database = database;
_webHostEnvironment = webHostEnvironment;
}
public IActionResult ShowBooks()
{
var books = _database.Books;
return View(books);
}
[HttpGet]
public IActionResult AddBook()
{
return View();
}
public async Task<IActionResult> AddBook(Book book)
{
if (ModelState.IsValid)
{
string wwwRootPath = _webHostEnvironment.WebRootPath;
string fileName = Path.GetFileNameWithoutExtension(book.Image.FileName);
string extention = Path.GetExtension(book.Image.FileName);
string path = Path.Combine(wwwRootPath "/booksImages", fileName);
using (var fileStream = new FileStream(path, FileMode.Create))
{
await book.Image.CopyToAsync(fileStream);
}
_database.Books.Add(book);
_database.SaveChanges();
return RedirectToAction("ShowBooks", "Admin");
}
return View(book);
}
}
}
The view that won't view:
@model IEnumerable<BookStore1.Models.Book>
@{
ViewData["Title"] = "ShowBooks";
}
<h1>ShowBooks</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<table >
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Author)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Author)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</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>
database context:
using Microsoft.EntityFrameworkCore;
using BookStore1.Models;
namespace BookStore1.Data
{
public class AppDataContext: DbContext
{
public AppDataContext(DbContextOptions<AppDataContext> options): base(options)
{
}
public DbSet<Account> Accounts { get; set; }
public DbSet<Book> Books { get; set; }
}
}
Thank for your time and help.
CodePudding user response:
you have to fix the action, to convert a dbset to a list and add name of the view to the action if name is not "ShowBooks.cshtml"
public IActionResult ShowBooks()
{
var books = _database.Books.ToList();
return View("viewName", books);
}
CodePudding user response:
If the view you shown above is ShowBooks.You only need to use _database.Books.ToList()
as Serge
said.
You use @model IEnumerable<BookStore1.Models.Book>
in the view,and you pass System.Collections.Generic.List
1[BookStore1.Models.Book]` to the view,it's correct.
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Collections.Generic.List`1[BookStore1.Models.Book]', but this ViewDataDictionary instance requires a model item of type 'BookStore1.Models.Account'.
For the error,the view will contains @model BookStore1.Models.Account
.You need to find the view which contains it,and check the data passed from action.