model item passed into the dictionary is of type PagedList.PagedList[] but this dictionary requires a model item of type - asp.net-mvc-4

Im trying to use view models in my project but I have this error:
The model item passed into the dictionary is of type
'PagedList.PagedList1[ContosoUniversity.Models.Course]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[ContosoUniversity.ViewModels.CourseViewModel]'.
Controller:
public ActionResult Index(int? page)
{
int pageNumber = page ?? 1;
var courses = courseService.GetAll();
var coursesViewList = Mapper.Map<IEnumerable<Course>, IEnumerable<CourseViewModel>>(courses);
var model = coursesViewList.ToPagedList(pageNumber, PageSize);
return View(model);
}
View:
#model IEnumerable<ContosoUniversity.ViewModels.CourseViewModel>
#using PagedList.Mvc;
#using PagedList;
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Title)
</th>
<th>
#Html.DisplayNameFor(model => model.Credits)
</th>
<th>
Students
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.Credits)
</td>
<td>
#string.Join(",", item.Enrollments.Select(e => e.Student.FullName))
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.CourseID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.CourseID })
</td>
</tr>
}
</table>
#Html.PagedListPager((IPagedList)Model, page => Url.Action("Index", new { page }))
Could somebody help me to resolve a problem please?

You are passing Model of type PagedList.PagedList1<ContosoUniversity.Models.Course> while your View is strongly typed with IEnumerable<ContosoUniversity.ViewModels.CourseViewModel>.
You need to pass IEnumerable<T> from action or set Model of View to PagedList<T> or you can overcome this issue by wrapping it inside a ViewModel in following way:
public class CoursesVM
{
public PagedList.IPagedList<CourseViewModel> Courses { get; set; }
}
In action:
public ActionResult Index(int? page)
{
int pageNumber = page ?? 1;
var courses = courseService.GetAll();
var coursesViewList = Mapper.Map<IEnumerable<Course>, IEnumerable<CourseViewModel>>(courses);
var model = new CoursesVM();
model.Courses = coursesViewList.ToPagedList(pageNumber, PageSize);
return View(model);
}
and in View:
#model ContosoUniversity.ViewModels.CoursesVM
#using PagedList.Mvc;
#using PagedList;
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Title)
</th>
<th>
#Html.DisplayNameFor(model => model.Credits)
</th>
<th>
Students
</th>
<th></th>
</tr>
#foreach (var item in Model.Courses) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.Credits)
</td>
<td>
#string.Join(",", item.Enrollments.Select(e => e.Student.FullName))
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.CourseID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.CourseID })
</td>
</tr>
}
</table>

Related

Space generated in action string

I am building a Asp.Net Core 2.1 EF MVC solution.
Instead of writing separate lines for each CRUD button (Edit, Create, Delete) in each of my Index views, I am trying to generate the buttons dynamically from a partial view as follows.
Models/AdmSchool
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace FACEZ.Models
{
public partial class AdmSchool
{
[Display(Name = "Id")]
public int AdmSchoolId { get; set; }
[Required]
[MaxLength(10)]
[Display(Name = "Code")]
public string AdmSchoolCode { get; set; }
[Required]
[MaxLength(100)]
[Display(Name = "School Name")]
public string AdmSchoolDescr { get; set; }
[MaxLength(100)]
[Display(Name = "Generic Email Principal")]
public string EmailPrincipal { get; set; }
[MaxLength(100)]
[Display(Name = "Generic Email Accounts")]
public string EmailAccounts { get; set; }
[MaxLength(100)]
[Display(Name = "Generic Email Registrar")]
public string EmailRegistrar { get; set; }
[Display(Name = "Obsolete")]
public bool Obsolete { get; set; }
}
}
Views/Shared/_IndividualButtonPartial
#model FACEZ.Models.IndividualButtonPartial
<a type="button" class="btn btn-sm #Model.ButtonType"
href="#Url.Action(Model.Action) #Model.ActionParameters">
<span class="glyphicon glyphicon-#Model.Glyph"></span>
<span class="sr-only">#Model.Text</span>
</a>
Views/Shared/_TableButtonPartial
#model FACEZ.Models.IndividualButtonPartial
<td style="width: 150px;">
<div class="btn-group" role="group">
#await Html.PartialAsync("_IndividualButtonPartial",
new IndividualButtonPartial {
Action="Edit",
ButtonType="btn-primary",
Glyph = "pencil",
Text = "Edit",
Id=Model.Id
})
#await Html.PartialAsync("_IndividualButtonPartial",
new IndividualButtonPartial {
Action="Details",
ButtonType="btn-success",
Glyph = "list",
Text = "Details",
Id=Model.Id
})
#await Html.PartialAsync("_IndividualButtonPartial",
new IndividualButtonPartial {
Action="Delete",
ButtonType="btn-danger",
Glyph = "trash",
Text = "Delete",
Id=Model.Id
})
</div>
</td>
Areas/Adm/Views/AdmSchools/Index.cshtml
#using Microsoft.EntityFrameworkCore.SqlServer.Query.ExpressionTranslators.Internal
#model IEnumerable<FACEZ.Models.AdmSchool>
#{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>
<a asp-action="Create">Create New</a>
</p>
<div class="form-border">
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.AdmSchoolCode)
</th>
<th>
#Html.DisplayNameFor(model => model.AdmSchoolDescr)
</th>
<th>
#Html.DisplayNameFor(model => model.EmailPrincipal)
</th>
<th>
#Html.DisplayNameFor(model => model.EmailAccounts)
</th>
<th>
#Html.DisplayNameFor(model => model.EmailRegistrar)
</th>
<th>
#Html.DisplayNameFor(model => model.Obsolete)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.AdmSchoolCode)
</td>
<td>
#Html.DisplayFor(modelItem => item.AdmSchoolDescr)
</td>
<td>
#Html.DisplayFor(modelItem => item.EmailPrincipal)
</td>
<td>
#Html.DisplayFor(modelItem => item.EmailAccounts)
</td>
<td>
#Html.DisplayFor(modelItem => item.EmailRegistrar)
</td>
<td>
#Html.DisplayFor(modelItem => item.Obsolete)
</td>
<td>
#await Html.PartialAsync("_TableButtonPartial", new IndividualButtonPartial {Id=item.AdmSchoolId})
#* I am trying to replace the following code with the line above
<a asp-action="Edit" asp-route-id="#item.AdmSchoolId">Edit</a> |
<a asp-action="Details" asp-route-id="#item.AdmSchoolId">Details</a> |
<a asp-action="Delete" asp-route-id="#item.AdmSchoolId">Delete</a>
*#
</td>
</tr>
}
</tbody>
</table>
When I run the app, I can see the school info in the Index view.
However, the action link that is being created, is getting a space in it from somewhere?
like https://localhost:44399/Adm/AdmSchools/Edit /1 instead of
like https://localhost:44399/Adm/AdmSchools/Edit/1
How can i remove the space after the action name.
In your _IndividualButtonPartial you do have a space between #Url.Action(Model.Action) and #Model.ActionParameters. This is what is getting reflected.

ASP.NET MVC4: How to hightlight selected row and send id corresponding to controller when click on edit or detail or delete link

I need help please. I'm using ASP.NET MVC 4. I have a view(Index.cshtml) that display data in table from sql database using entity framework. I want to know how to hightlight selected row and send specific id(id_equipment) to one html.actionlink for editing, deleting or viewing details.
Here's my view:
#model IEnumerable<TEST.Models.equipment>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
#Html.ActionLink("Edit", "Edit", new { id = /*item.id_equipment*/ }) |
#Html.ActionLink("Details", "Details", new { id = /*item.id_equipment*/ }) |
#Html.ActionLink("Delete", "Delete", new { id = /*item.id_equipment*/ })
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.id_equipment)
</th>
<th>
#Html.DisplayNameFor(model => model.name)
</th>
<th>
#Html.DisplayNameFor(model => model.type)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.id_equipment)
</td>
<td>
#Html.DisplayFor(modelItem => item.name)
</td>
<td>
#Html.DisplayFor(modelItem => item.type)
</td>
</tr>
}
</table>
Thank you!

In a column of Credits, show the amount of credits for all courses for which student enlisted

How to in a column of Credits show the amount of credits for all courses for which student enlisted.
I need to modify a Contoso University app.
View:
#model PagedList.IPagedList<ContosoUniversity.Models.Student>
#using PagedList.Mvc;
<h2>Students</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
#using (Html.BeginForm("Index", "Student", FormMethod.Get))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<p>
Find by name: #Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Filter" />
</p>
}
<table class="table">
<tr>
<th>
#Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm })
</th>
<th>
First Name
</th>
<th>
#Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm })
</th>
<th>
Date Of Birth
</th>
<th>
Courses
</th>
<th>
Credits
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstMidName)
</td>
<td>
#Html.DisplayFor(modelItem => item.EnrollmentDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateOfBirth)
</td>
<td>
#string.Join(",", item.Enrollments.Select(e => e.Course.Title))
</td>
<td>
</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>
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
Please Help!
I dont understand how to do it!
If somebody need more details please tell me.
I don't have any experience with Contoso University, but it seems to me that you may be able to sum the credits by doing something like this:
item.Enrollments.Sum(e => e.Course.Credits);
This is untested and it's hard to know for sure if this will work without knowing how the data is structured, but I'm sure looking at the Sum() method will help you out.
#item.Enrollments.Sum(e => e.Course.Credits)

Cannot Access ViewModel Class member inside razor view

I cannot access a member of my class inside the view. All other members are accessible.
The following member "ListOfCategories" is not available in intellisense or at run time inside the view.
Error: There is no ViewData item of type 'IEnumerable' that has the key 'ListOfCategories'
My ViewModelClass
public class ArticleEditViewModel
{
public int ID { get; set; }
[Required]
public string Title { get; set; }
public List<Category> ListOfCategories = new List<Category>();
}
My Razor View
#model rrrr.ViewModels.Article.ArticleEditViewModel
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_LayoutSecure.cshtml";
}
<div>
#Html.ActionLink("Back to Articles", "Index")
</div>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.ID)
<div class="tableHeader">
<h2>Update Article</h2>
</div>
<table id="RegistrationForm">
<tbody>
<tr>
<td>Title</td>
<td>
#Html.TextBoxFor(model => model.Title, new { #class = "registerinput" })
</td>
<td class="leftWarning">
#Html.ValidationMessageFor(model => model.Title)
</td>
</tr>
<tr>
<td>Category</td>
<td>
#Html.DropDownList(model => model.ListOfCategories, Model.CategoryID)
</td>
<td class="leftWarning">
#Html.ValidationMessageFor(model => model.CategoryID)
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="Update Article" class = "css_button_4" />
</td>
</tr>
</tbody>
</table>
}
Use DropdownListFor instead. The code will be something like this:
#Html.DropDownListFor(model => model.CategoryId, Model.ListOfCategories.Select(c => new SelectListItem { Text = c.CategoryName, Value = c.CategoryId }))

How do I add a filtering option in ASP.NET?

I am building an ASP.Net MVC webpage which will display server information. It will also allow us to edit the owners of each server without having to use Management Studio.
I works fine, but I want to add a filtering feature so that I view the ServerNames I choose (how you can filter an excel spreadsheet after you have implemented the filter feature on the headings).
I have been using the following tutorial:
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application
Some added information: I connected a database on a server, and the information I am displaying is from 3 different tables.
Any help is greatly appreciated!
This is my index view code:
#model IEnumerable<SQL_Server_Inventory_UI.ServerList>
#{
ViewBag.Title = "Index";
}
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
ServerName
</th>
<th>
InstanceName
</th>
<th>
PortNumber
</th>
<th>
IsMonitored
</th>
<th>
Environment
</th>
<th>
SQLVersion
</th>
<th>
SQLServicePack
</th>
<th>
SQLProductVersion
</th>
<th>
RetireDate
</th>
<th>
IPAddress
</th>
<th>
IsVMW
</th>
<th>
Platform
</th>
<th>
IsLiteSpeedUsed
</th>
<th>
Domain
</th>
<th>
CreateDate
</th>
<th>
LastUpdateDate
</th>
<th>
CName
</th>
<th>
IsStandby
</th>
<th>
Server_Group
</th>
<th>
TeamMember
</th>
<th>
IsMissionCritical
</th>
<th>
IsCluster
</th>
<th>
DBANotes
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.ServerName)
</td>
<td>
#Html.DisplayFor(modelItem => item.InstanceName)
</td>
<td>
#Html.DisplayFor(modelItem => item.PortNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.IsMonitored)
</td>
<td>
#Html.DisplayFor(modelItem => item.Environment)
</td>
<td>
#Html.DisplayFor(modelItem => item.SQLVersion)
</td>
<td>
#Html.DisplayFor(modelItem => item.SQLServicePack)
</td>
<td>
#Html.DisplayFor(modelItem => item.SQLProductVersion)
</td>
<td>
#Html.DisplayFor(modelItem => item.RetireDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.IPAddress)
</td>
<td>
#Html.DisplayFor(modelItem => item.IsVMW)
</td>
<td>
#Html.DisplayFor(modelItem => item.Platform)
</td>
<td>
#Html.DisplayFor(modelItem => item.IsLiteSpeedUsed)
</td>
<td>
#Html.DisplayFor(modelItem => item.Domain)
</td>
<td>
#Html.DisplayFor(modelItem => item.CreateDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastUpdateDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.CName)
</td>
<td>
#Html.DisplayFor(modelItem => item.IsStandby)
</td>
<td>
#Html.DisplayFor(modelItem => item.Server_Group.GroupName)
</td>
<td>
#Html.DisplayFor(modelItem => item.TeamMember.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.IsMissionCritical)
</td>
<td>
#Html.DisplayFor(modelItem => item.IsCluster)
</td>
<td>
#Html.DisplayFor(modelItem => item.DBANotes)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ServerId }) |
#Html.ActionLink("Details", "Details", new { id=item.ServerId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ServerId })
</td>
</tr>
}
</table>
This is my controller code:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SQL_Server_Inventory_UI;
namespace SQL_Server_Inventory_UI.Controllers
{
public class ServerListController : Controller
{
private ServerListConnectionEntities db = new ServerListConnectionEntities();
//
// GET: /ServerList/
public ViewResult Index()
{
var serverlists = db.ServerLists.Include("Server_Group").Include("TeamMember");
return View(serverlists.ToList());
}
//
// GET: /ServerList/Details/5
public ViewResult Details(int id)
{
ServerList serverlist = db.ServerLists.Single(s => s.ServerId == id);
return View(serverlist);
}
//
// GET: /ServerList/Create
public ActionResult Create()
{
ViewBag.GroupID = new SelectList(db.Server_Group, "GroupID", "GroupName");
ViewBag.OwnerID = new SelectList(db.TeamMembers, "MemberID", "Name");
return View();
}
//
// POST: /ServerList/Create
[HttpPost]
public ActionResult Create(ServerList serverlist)
{
if (ModelState.IsValid)
{
db.ServerLists.AddObject(serverlist);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.GroupID = new SelectList(db.Server_Group, "GroupID", "GroupName", serverlist.GroupID);
ViewBag.OwnerID = new SelectList(db.TeamMembers, "MemberID", "Name", serverlist.OwnerID);
return View(serverlist);
}
//
// GET: /ServerList/Edit/5
public ActionResult Edit(int id)
{
ServerList serverlist = db.ServerLists.Single(s => s.ServerId == id);
ViewBag.GroupID = new SelectList(db.Server_Group, "GroupID", "GroupName", serverlist.GroupID);
ViewBag.OwnerID = new SelectList(db.TeamMembers, "MemberID", "Name", serverlist.OwnerID);
return View(serverlist);
}
//
// POST: /ServerList/Edit/5
[HttpPost]
public ActionResult Edit(ServerList serverlist)
{
if (ModelState.IsValid)
{
db.ServerLists.Attach(serverlist);
db.ObjectStateManager.ChangeObjectState(serverlist, EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.GroupID = new SelectList(db.Server_Group, "GroupID", "GroupName", serverlist.GroupID);
ViewBag.OwnerID = new SelectList(db.TeamMembers, "MemberID", "Name", serverlist.OwnerID);
return View(serverlist);
}
//
// GET: /ServerList/Delete/5
public ActionResult Delete(int id)
{
ServerList serverlist = db.ServerLists.Single(s => s.ServerId == id);
return View(serverlist);
}
//
// POST: /ServerList/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
ServerList serverlist = db.ServerLists.Single(s => s.ServerId == id);
db.ServerLists.DeleteObject(serverlist);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
Change your Index controller to something like this:
public ViewResult Index(string filter)
{
var serverlists = db.ServerLists.Include("Server_Group").Include("TeamMember");
if (!string.IsNullorEmpty(filter))
serverlists = serverlists.Where(sl => sl.Name.StartsWith(filter);
return View(serverlists.ToList());
}
Then change your view to post back with a filter {url}?filter=stringtosearchfor when you need the list filtered. This won't give you AJAX-style filtering, but will get you your intended response.