Link not rendering when using asp-page TagHelper - c#

I have one page that does not render a link in HTML when using the asp-page TagHelper. I have seen this before, but it was due to a typo or the page not existing.
Of the two links in the _Layout below,
Users renders as http://localhost/ReportGroups/Admin/Users
Roles renders as http://localhost/ReportGroups
Navigating to Roles manually results in a 404 error.
_Layout.cshtml
The link is part of an Admin menu. The commented out FontAwesome icons are part of my testing. /Admin/Users works fine, but /Admin/RoleList does not work. It was previously /Admin/Roles but I built a new copy of the file up in parts to see if anything was throwing an error, or if it was a reserved word.
#if (User.Identity.IsAuthenticated)
{
if (User.IsInRole("Admin"))
{
<div id="nav-admin">
<ul>
<li><a asp-page="/Admin/Users"> Users</a></li>#*< i class="fas fa-user-secret" title="Users"></i>*#
<li><a asp-page="/Admin/RoleList"> Roles</a></li>
#*<i class="fas fa-id-card" title="Roles"></i>*#
</ul>
</div>
}
}
RoleList.cshtml
#page "{roleId}/{userId}"
#model RoleListModel
#{
ViewData["PageTitle"] = "Admin Tools - Roles";
ViewData["IconClass"] = "";
ViewData["IconTitle"] = "Roles";
}
<table>
<thead>
<tr>
<th>Role</th>
<th>User Name</th>
<th>First Name</th>
<th>Last Name</th>
<th> </th>
</tr>
</thead>
<tbody>
#foreach (ApplicationRole role in Model.AppRoles)
{
<tr>
<td colspan="4"><strong>#role.Name</strong></td>
<td>
<a asp-page="/App/RoleEdit" asp-route-roleId="#role.Id"><i class="fas fa-edit"></i></a>
</td>
</tr>
IList<ApplicationUser> usersOfRole = Model.AppRoleUsersDict[role];
foreach (ApplicationUser user in usersOfRole)
{
<tr>
<td>#role.Name</td>
<td>#user.UserName</td>
<td>#user.FirstName</td>
<td>#user.LastName</td>
<td>
<form method="post" asp-page-handler="delete">
<button type="submit" asp-page="/App/GroupEdit" asp-page-handler="delete" asp-route-roleId="#role.Id" asp-route-userId="#user.Id">
<i class="fas fa-trash-alt" style="color:red"></i>
</button>
</form>
</td>
</tr>
}
}
</tbody>
</table>
RoleList.cshtml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Ctrack.ReportGroups.Data;
using Ctrack.ReportGroups.Identity;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Ctrack.ReportGroups.Pages
{
public class RoleListModel : PageModel
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly ApplicationDbContext _db;
public RoleListModel(
ApplicationDbContext db,
UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager)
{
_db = db;
_userManager = userManager;
_roleManager = roleManager;
}
public IList<ApplicationRole> AppRoles { get; set; }
public IDictionary<ApplicationRole, IList<ApplicationUser>> AppRoleUsersDict { get; set; }
/// <summary>
/// List all Roles, and the Users assigned to them. Exposes a form to delete the relationship for each user.
/// </summary>
/// <returns>Task>IActionResult></returns>
public async Task<IActionResult> OnGetAsync()
{
AppRoles = _roleManager.Roles.ToList();
AppRoleUsersDict = new Dictionary<ApplicationRole, IList<ApplicationUser>>();
foreach (ApplicationRole role in AppRoles)
{
IList<ApplicationUser> usersOfRole = await _userManager.GetUsersInRoleAsync(role.Name);
AppRoleUsersDict.Add(role, usersOfRole);
}
return Page();
}
/// <summary>
/// Removes a role from a User
/// </summary>
/// <param name="roleId"><see langword="string"/> containing RoleId</param>
/// <param name="userId"><see langword="string"/> containing UserId</param>
/// <returns>Task>IActionResult></returns>
public async Task<IActionResult> OnPostDeleteAsync(string roleId, string userId)
{
ApplicationUser user = await _userManager.FindByIdAsync(userId);
ApplicationRole role = await _roleManager.FindByIdAsync(roleId);
try
{
await _userManager.RemoveFromRoleAsync(user, role.Name);
TempData["Notification"] = $"Successfully removed Role {role.Name} from User {user.UserName}.";
}
catch (Exception ex)
{
TempData["ErrorMessage"] = $"Exception {ex.GetType()} encountered while removing Role {role.Name} from User {user.UserName}.";
}
return Page();
}
}
}
_ViewImports.cshtml
#using Microsoft.AspNetCore.Identity
#using CtrackReportGroupsRtca
#using Ctrack.ReportGroups.Data
#using Ctrack.ReportGroups.Identity
#using System.Security.Claims
#using Microsoft.AspNetCore.Html;
#namespace Ctrack.ReportGroups.Pages
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Related

C# razor input var to controller search sql

I am doing what should be a basic programming item but I seem to be missing something on how MVC works. I have a web page that gets inventory items from a database and displays them. I added a partial view that has a menu bar that I want to use on other views (at this point not robust). In the menu bar I added a text box and search button. I want to search the inventory database for the text entered in the text box. I can't seem to get the InventoryController to allow me to add a select statement so I can return the data to the list view. Maybe the partial view and view don't interact like I hoped they would.
Should I think of partial views added to a view as not sharing input data?
Can I do a select/find search using this format or should I use multiple controllers/views?
List.cshtml
#model WebUI.Models.InventoryListViewModel1
#{
ViewBag.Title = "Items";
}
#Html.Partial("MenuView1")
<h2>test</h2>
<div>
<table class="productTable">
<thead>
<tr>
<th class="item">Item</th>
<th class="descrip">Description</th>
<th class="color">Color</th>
<th class="height">Height</th>
<th class="width">Width</th>
<th class="depth">Depth</th>
<th class="manuf">Manufacturer</th>
<th class="manpartno">ManPartNo</th>
<th class="barcode">BarCodeNo</th>
<th class="qtyOnHnd">In Stock</th>
<th class="qtyOnOrdr">On Order</th>
</tr>
</thead>
#foreach (var p in Model.Inventory)
{
<tr id="itemRow">
<td class="item">#p.item</td>
<td class="descrip">#p.description</td>
<td class="color">#p.color</td>
<td class="height">#p.height</td>
<td class="width">#p.width</td>
<td class="depth">#p.depth</td>
<td class="manuf">#p.manufacturer</td>
<td class="manpartno">#p.manPartNo</td>
<td class="barcode">#p.barCodeNo</td>
<td class="qtyOnHnd"></td>
<td class="qtyOnOrdr"></td>
</tr>
}
</table>
</div>
<div class="pager">
#Html.PageLinks(Model.PagingInfo1, x => Url.Action("List", new {page = x}))
</div>
MenuView1.cshtml
#{
var inventoryItem = "";
if (IsPost)
{
inventoryItem = Request["inventorysearch"];
}
<form method="post">
<div>
<ul>
<li class="mainMenuBar">Home</li>
<li class="mainMenuBar">Inventory</li>
<li class="mainMenuBar">Clients</li>
<li class="mainMenuBar">
<input type="text" name="inventorySearch" /></li>
<li class="mainMenuBar">
<input type="submit" value="Search" /></li>
</ul>
</div>
</form>
}
InventoryListViewModel1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DomainClasses.entities;
namespace WebUI.Models
{
public class InventoryListViewModel1
{
public IQueryable<InventoryClass1> Inventory { get; set; }
public PagingInfo1 PagingInfo1 { get; set; }
}
}
InventoryController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DomainClasses.Abstract;
using DomainClasses.entities;
using DomainClasses.concrete;
using WebUI.Models;
namespace WebUI.Controllers
{
public class InventoryController : Controller
{
private IInventoryRepository1 repository;
public int PageSize = 5;
public InventoryController(IInventoryRepository1 inventoryRepository)
{
this.repository = inventoryRepository;
}
//
// GET: /Invenotry/
public ViewResult List(int page = 1)
{
InventoryListViewModel1 model = new InventoryListViewModel1
{
Inventory = repository.inventory
.OrderBy(p => p.item)
.Skip((page - 1) * PageSize)
.Take(PageSize),
PagingInfo1 = new PagingInfo1
{
CurrentPage = page,
ItemsPerPage = PageSize,
TotalItems = repository.inventory.Count()
}
};
return View(model);
}
public ViewResult MenuView1(string inventorysearch)
{
InventoryListViewModel1 model = new InventoryListViewModel1
{
Inventory = repository.inventory
.Select (recieve and error that Select is a bad method)
};
}
}
}

How do I retrieve a listing of a form?

I carry a list with information that comes from my database. This is displayed in a form where the user can edit a field. My intention is when they click the save button this list being displayed for him would pass as a parameter to a method. I'm lost, what is wrong?
View
#model Teste.Models.Produto
#{
Layout = null;
}
#using (Html.BeginForm("Salvar", "ListaProdutoCab", FormMethod.Post))
{
<table>
<thead>
<tr>
<th>Selecione</th>
<th>Produto</th>
<th>Valor</th>
</tr>
</thead> #foreach (var item in Model.listaBebida)
{
<tr>
<td> #Html.CheckBoxFor(modelItem => item.isEditado)</td>
<td> #Html.TextBoxFor(modelItem => item.produto, new { disabled = "disabled" }) </td>
<td> #Html.TextBoxFor(modelItem => item.valor) </td>
</tr>
}
</table>
<div id="modal">
<div id="botoes">
<button type="submit">Salvar</button>
</div>
</div>
}
my Controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Teste.DAO;
using Teste.Models;
namespace Teste.Controllers
{
public class ListaProdutoCab: Controller
{
//
// GET: /ListaProdutoCab/
ListaProdutoService service = new ListaProdutoService();
Produto produto = new Produto();
Session usuario = new Session("Genisson", 058);
List<ObjectMasterProduto> listaProduto= new List<ObjectMasterProduto>();
public ActionResult ListaProdutoCab()
{
return View();
}
public ActionResult List()
{
service.carregarListaBebida(produto.listaBebida);
return PartialView(produto);
}
[HttpPost]
public ActionResult Salvar(Produto produto)
{
service.Salvar(produto.listaBebida, usuario);
return RedirectToAction("List");
}
}
}
my entity
Produto
public class Produto
{
//Chamadas externas
public Bebida bebida{ get; set; }
public List<Bebida> listaBebida{ get; set; }
public Produto()
{
}
}
my other entity, Class bebida
public class Bebida
{
//Chamadas externas
public String nome{ get; set; }
public Double Valor{ get; set; }
public Bebida()
{
}
}
Your use of a foreach loop is creating duplicate id attributes (invalid html) and duplicate name attributes which have no relationship to you model and therefore cannot be bound to your model when you submit. Change it to a for loop
#for(int i = 0; i < Model.listaBebida.Count, i++)
{
<tr>
<td>#Html.CheckBoxFor(m => m.listaBebida[i].isEditado)</td>
<td>#Html.TextBoxFor(m => m.listaBebida[i].produto)</td>
<td>#Html.TextBoxFor(m => m.listaBebida[i].valor) </td>
</tr>
}
This will generate the correct name attributes, for example
<input type="text" name="listaBebida[0].valor" ... />
<input type="text" name="listaBebida[1].valor" ... />
<input type="text" name="listaBebida[2].valor" ... />
Side note: You have included the disabled attribute for produto which means that property will be null in the model when you submit (disabled form controls do not post back a value). If you want binding, then make it readonly
in these cases which values of some list should be posted, get values from form manually without model binding.
In your question i'm considering you have a unique identifier in your Bebida class like Bebida.Id, so the sample code may be:
such this:
#model Teste.Models.Produto
#{
Layout = null;
}
#using (Html.BeginForm("Salvar", "ListaProdutoCab", FormMethod.Post))
{
<table>
<thead>
<tr>
<th>Selecione</th>
<th>Produto</th>
<th>Valor</th>
</tr>
</thead> #foreach (var item in Model.listaBebida)
{
<tr>
<td> <input type='checkbox' name='chk_#item.Id' /> </td>
<td> <input type='text' name='produto_#item.Id' /> </td>
<td> <input type='text' name='valor_#item.Id' /> </td>
</tr>
}
</table>
<div id="modal">
<div id="botoes">
<button type="submit">Salvar</button>
</div>
</div>
}
and in your action :
[HttpPost]
public ActionResult Salvar()
{
var checkboxkeys = Request.Form.AllKeys.Where(k=>k.Contains("chk_"));
var CheckedCheckboxesId =checkboxkeys.Select(k=> Convert.ToInt32( k.Substring(4,k.Length-4)));
var produtokeys = Request.Form.AllKeys.Where(k=>k.Contains("produto_"));
var produtos= new Dictionary<int,string>();
foreach(var item in produtokeys )
{
produtos.Add(Convert.ToInt32( item.Substring(8,k.Length-8)),Request.Form[item]);
}
var valorkeys = Request.Form.AllKeys.Where(k=>k.Contains("valor_"));
var valors= new Dictionary<int,string>();
foreach(var item in valorkeys )
{
valors.Add(Convert.ToInt32( item.Substring(6,k.Length-6)),Request.Form[item]);
}
// in here you have CheckedCheckboxesId, produtos and valors and you may want store them.
return RedirectToAction("List");
}

Two login screen in one view MVC c#

What I am trying to do is create a login page with two login screen for two different type of users.
For One Login Screen, I did this-
I created a model like-
public class User1{
[Required(ErrorMessage = "MSG1", AllowEmptyStrings = false)]
public string Id {get; set;}
[Required(ErrorMessage = "MSG2", AllowEmptyStrings = false)]
[DataType(System.ComponentModel.DataAnnotations.DataType.Password)]
public string Password {get; set;}
}
Form -
#model Test.Models.User1
#using (Html.BeginForm("Login", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
if (#ViewBag.Message != null)
{
<div style="border: 1px solid red">
#ViewBag.Message
</div>
}
<table>
<tr>
<td>#Html.LabelFor(a => a.Id)</td>
<td>#Html.TextBoxFor(a => a.Id)</td>
<td>#Html.ValidationMessageFor(a => a.Id)</td>
</tr>
<tr>
<td>
#Html.LabelFor(a => a.Password)
</td>
<td>
#Html.PasswordFor(a => a.Password)
</td>
<td>
#Html.ValidationMessageFor(a => a.Password)
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="Login" />
</td>
<td></td>
</tr>
</table>
}
And the controller is -
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(User1 u)
{
if (ModelState.IsValid)
{
//My Code
}
return View(u);
}
I want to add another login screen here for User2 Type. Can this be possible on the same view??
If there is no difference between the fields that each user type uses to login (i.e. if they both use Id and Password) then I would suggest using the one 'User' model to bind to on your controller and then within your controller handle how you will figure out of what type of user it is and return an appropriate view.
Alternatively, if you can't do this you can just add a second Login form that posts to a different action on the controller (i.e. LoginUserType2). For example:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LoginUserType1(User1 u)
{
if (ModelState.IsValid)
{
//My Code
}
return View(u);
}
..
..
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LoginUserType2(User1 u)
{
if (ModelState.IsValid)
{
//My Code
}
return View(u);
}
Edit:
The way I would do this would be to create a UserViewModel class that represents all the fields on the page. For example:
public class UserViewModel
{
public string Username { get; set; }
public int UserId { get; set; }
public string PasswordType1 { get; set; }
public string PasswordType2 { get; set; }
}
This could then be used as the model for the page and you could post it to both actions as below:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LoginUserType1(UserViewModel u)
{
if (ModelState.IsValid)
{
// Login with UserId and PasswordType1
}
return View(u);
}
..
..
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LoginUserType2(UserViewModel u)
{
if (ModelState.IsValid)
{
// Login with Username and PasswordType2
}
return View(u);
}
Each form would post to one of the two actions and you could use whatever fields from the ViewModel as needed in each case. It's not ideal but I think it will work for what you want.
You should probably use editor templates, they allow a hierarchical display of data. For example you could do:
public class User1 {}
public class User2 {}
public class Login
{
public object User { get; set; }
}
Login.cshtml:
#model Login
<!-- container html for login screen -->
<div>
#Html.EditorFor(m => m.User);
</div>
/EditorTemplates/User1.cshtml:
#model User1
#using (Html.BeginForm("LoginUser1", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
if (#ViewBag.Message != null)
{
<div style="border: 1px solid red">
#ViewBag.Message
</div>
}
<table>
<tr>
<td>#Html.LabelFor(a => a.Id)</td>
<td>#Html.TextBoxFor(a => a.Id)</td>
<td>#Html.ValidationMessageFor(a => a.Id)</td>
</tr>
<tr>
<td>
#Html.LabelFor(a => a.Password)
</td>
<td>
#Html.PasswordFor(a => a.Password)
</td>
<td>
#Html.ValidationMessageFor(a => a.Password)
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="Login" />
</td>
<td></td>
</tr>
</table>
}
I have done this with the help of ViewBag like this. First in your Controller
create a dynamic property with ViewBag like if your user is of type1 then
public ActionResult Index()
{
//check your user type and set it to true/false
ViewBag.UserType1 = true;
}
if(ViewBag.UserType1 != null)
{
#if (Convert.ToBoolean(ViewBag.UserType1))
{
//Return view for user of type1
}
else
{
//return view for user of type2
}
}

I am getting MVC5 error (cannot be constructed in a LINQ to Entities query)

Every time I launched webpage for Index I keep getting this error. I cannot figure out the issue. It might be something simple I am over looking. If anyone has an idea that would be very much appreciated. I am not sure if the error is from the paging or the search feature.
Here is the picture of the error it is on the index ActionResult
ScannerAssignment Controller
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using ScannerAssignmentList.Models;
using PagedList;
namespace ScannerAssignmentList.Controllers
{
public class ScannerAssignmentController : Controller
{
private ScannerAssignmentDb _db = new ScannerAssignmentDb();
// GET: ScannerAssignment
public ActionResult Index(int? page, string searchTerm = null)
{
var model =
_db.ScannerAssignment
.OrderByDescending(r => r.EmployeeName)
.Where(r => searchTerm == null || r.EmployeeName.Contains(searchTerm) || r.Model.Contains(searchTerm) || r.Department.Contains(searchTerm) || r.EmployeeNumber.ToString().Contains(searchTerm) || r.Serial.ToString().Contains(searchTerm))
.Select(r => new ScannerAssignmentModel
{
Id = r.Id,
EmployeeName = r.EmployeeName,
EmployeeNumber = r.EmployeeNumber,
Model = r.Model,
Serial = r.Serial,
Department = r.Department
});
// return View(model);
return View(model.ToPagedList(page ?? 1, 5));
}
// GET: ScannerAssignment/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ScannerAssignmentModel scannerAssignmentModel = _db.ScannerAssignment.Find(id);
if (scannerAssignmentModel == null)
{
return HttpNotFound();
}
return View(scannerAssignmentModel);
}
// GET: ScannerAssignment/Create
public ActionResult Create()
{
return View();
}
// POST: ScannerAssignment/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,EmployeeName,EmployeeNumber,Model,Serial,Department,Comments")] ScannerAssignmentModel scannerAssignmentModel)
{
if (ModelState.IsValid)
{
_db.ScannerAssignment.Add(scannerAssignmentModel);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(scannerAssignmentModel);
}
// GET: ScannerAssignment/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ScannerAssignmentModel scannerAssignmentModel = _db.ScannerAssignment.Find(id);
if (scannerAssignmentModel == null)
{
return HttpNotFound();
}
return View(scannerAssignmentModel);
}
// POST: ScannerAssignment/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,EmployeeName,EmployeeNumber,Model,Serial,Department,Comments")] ScannerAssignmentModel scannerAssignmentModel)
{
if (ModelState.IsValid)
{
_db.Entry(scannerAssignmentModel).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(scannerAssignmentModel);
}
// GET: ScannerAssignment/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ScannerAssignmentModel scannerAssignmentModel = _db.ScannerAssignment.Find(id);
if (scannerAssignmentModel == null)
{
return HttpNotFound();
}
return View(scannerAssignmentModel);
}
// POST: ScannerAssignment/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
ScannerAssignmentModel scannerAssignmentModel = _db.ScannerAssignment.Find(id);
_db.ScannerAssignment.Remove(scannerAssignmentModel);
_db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_db.Dispose();
}
base.Dispose(disposing);
}
}
}
Here is the View for the Index ActionResult
#using PagedList;
#using PagedList.Mvc;
#model IPagedList<ScannerAssignmentList.Models.ScannerAssignmentModel>
#{
ViewBag.Title = "Index";
}
<br />
<div class="panel panel-primary">
<div class="panel-heading">
<h1 class="panel-title">Search Area</h1>
</div>
<div class="panel-body">
<div class="form-group">
<form method="get">
#Html.TextBox("searchTerm", null, new { #class = "form-control" })<span class="input-group-btn"></span>
<div class="panel-footer">
<button id="btnSearch"
class="btn btn-sm btn-primary">
<i class="glyphicon glyphicon-search"></i>
Search
</button>
<a href="#Url.Action("Index", "ScannerAssignment")" class="btn btn-sm btn-primary">
<span class="glyphicon glyphicon-cog" aria-hidden="true"></span>
Reset
</a>
<a href="#Url.Action("Create", "ScannerAssignment")" class="btn btn-sm btn-primary">
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
Add
</a>
</div>
</form>
</div>
</div>
</div>
<p>
#Html.ActionLink("Add New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.First().EmployeeName)
</th>
<th>
#Html.DisplayNameFor(model => model.First().EmployeeNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.First().Model)
</th>
<th>
#Html.DisplayNameFor(model => model.First().Serial)
</th>
<th>
#Html.DisplayNameFor(model => model.First().Department)
</th>
<th>
#Html.DisplayNameFor(model => model.First().Comments)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.EmployeeName)
</td>
<td>
#Html.DisplayFor(modelItem => item.EmployeeNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.Model)
</td>
<td>
#Html.DisplayFor(modelItem => item.Serial)
</td>
<td>
#Html.DisplayFor(modelItem => item.Department)
</td>
<td>
#Html.DisplayFor(modelItem => item.Comments)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
#Html.ActionLink("Details", "Details", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
#Html.PagedListPager(Model, page => Url.Action("Index", new { page, searchterm = Request.QueryString["searchterm"] }),
new PagedListRenderOptions() { Display = PagedListDisplayMode.IfNeeded, DisplayPageCountAndCurrentLocation = true, DisplayItemSliceAndTotal = true })
ScannerAssignment Model
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace ScannerAssignmentList.Models
{
public class ScannerAssignmentModel
{
[Key]
public int Id { get; set; }
public string EmployeeName { get; set; }
public int EmployeeNumber { get; set; }
public string Model { get; set; }
public string Serial { get; set; }
public string Department { get; set; }
public string Comments { get; set; }
}
}
ScannerAssignmentDb
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace ScannerAssignmentList.Models
{
public class ScannerAssignmentDb :DbContext
{
public ScannerAssignmentDb()
: base("name=DefaultConnection")
{
}
public DbSet<ScannerAssignmentModel> ScannerAssignment{ get; set; }
}
}

ASP.Net MVC “The model item passed into the dictionary is of type 'System.Collections.Generic.List”

View
#using LearningMVCBLL;
#model LearningMVC.Models.User
#{
ViewBag.Title = "CityDetails";
}
<h2>CityDetails</h2>
<table>
<thead>
<tr>
<th>ID</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>City Name</td>
<td>#foreach (CityMaster city in #Model.GetCityDetails())
{
#city.City_Name
}
</td>
</tr>
#* <tr>
<td></td>
<td></td>
</tr>*#
</tbody>
</table>
Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LearningMVC.Models;
using LearningMVCBLL;
namespace LearningMVC.Controllers
{
public class UserController : Controller
{
//
// GET: /Index/
public ActionResult CityDetails()
{
User User = new User();
List<CityMaster> city = new List<CityMaster>();
city = User.GetCityDetails();
return View(city);
}
}
}
Model
using LearningMVCBLL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace LearningMVC.Models
{
public class User
{
LearningMVCDataContext _dbContext = new LearningMVCDataContext();
public List<CityMaster> GetCityDetails()
{
List<CityMaster> city = _dbContext.CityMasters.Where(c => c.City_ID == 2).ToList();
return city;
}
}
}
I am new to MVC please help me in resolving this problem. Error that I am getting is "The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[LearningMVCBLL.CityMaster]', but this dictionary requires a model item of type 'LearningMVC.Models.User'."
I am using LINQ to fetch the data from the database. Please explain me what I am doing wrong or I am completely wrong.
In your action method you have this code...
public ActionResult CityDetails()
{
User User = new User();
List<CityMaster> city = new List<CityMaster>();
city = User.GetCityDetails();
return View (city);
}
You need to change it to this....
public ActionResult CityDetails()
{
User user = new User();
return View(user);
}
You may use Leo answer, if you want have User in view. Or you may change view:
Replace model
#model LearningMVC.Models.User
To
#model List<CityMaster>
And in foreach replace
#foreach (CityMaster city in #Model.GetCityDetails())
To
#foreach (CityMaster city in Model)
Although you already have an answer you'd be better of constructing the data you need in the controller.
Example:
public class CityDetailsModel
{
public User User { get; set; }
public IEnumerable<Cities> { get; set; }
}
public class UserController : Controller
{
//
// GET: /Index/
public ActionResult CityDetails()
{
CityDetailsModel model = new CityDetailsModel();
model.User = new User();
model.Cities = GetCityDetails();
return View(model);
}
}
View:
#using LearningMVCBLL;
#model LearningMVC.Models.CityDetailsModel
#{
ViewBag.Title = "CityDetails";
}
<h2>CityDetails</h2>
<table>
<thead>
<tr>
<th>ID</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>City Name</td>
<td>
#foreach (CityMaster city in #Model.Cities)
{
#city.City_Name
}
</td>
</tr>
#* <tr>
<td></td>
<td></td>
</tr>*#
</tbody>
</table>

Resources