foreach statement cannot operate on variables MVC3 error - c#

Here is the definition of CourseRegisterModel:
public class CourseRegisterModel
{
public StudentModel Student { get; set; }
public CourseModel Course { get; set; }
public CourseModel Course1 { get; set; }
public CourseModel Course2 { get; set; }
public CourseModel Course3 { get; set; }
public CourseModel Course4 { get; set; }
public CourseModel Course5 { get; set; }
public List<SelectListItem> CoursesList { get; set; }
public DateTime RegisterDate { get; set; }
}
Here is my controller function which executes on Home Page load:
public ActionResult Home()
{
//Retrieve all registered courses for this bloody student
ServiceCourseClient client = new ServiceCourseClient();
Course[] coursespending;
var loggedInRollNumber = Request.Cookies["RollNumber"].Value;
coursespending = client.GetPendingRegisteredCourses(loggedInRollNumber.ToString());
List<CourseRegisterModel> coursesRegisteredmodelList = new List<CourseRegisterModel>();
CourseRegisterModel CRM = null;
int i = 0;
foreach (var serviceCourseRegistered in coursespending)
{
CRM = new CourseRegisterModel();
if (i == 0)
{
CRM.Course1.Code = serviceCourseRegistered.Code;
CRM.Course1.Name = serviceCourseRegistered.Name;
}
else if (i == 1)
{
CRM.Course2.Code = serviceCourseRegistered.Code;
CRM.Course2.Name = serviceCourseRegistered.Name;
}
else if (i == 2)
{
CRM.Course3.Code = serviceCourseRegistered.Code;
CRM.Course3.Name = serviceCourseRegistered.Name;
}
else if (i == 3)
{
CRM.Course4.Code = serviceCourseRegistered.Code;
CRM.Course4.Name = serviceCourseRegistered.Name;
}
else if (i == 4)
{
CRM.Course5.Code = serviceCourseRegistered.Code;
CRM.Course5.Name = serviceCourseRegistered.Name;
}
i++;
coursesRegisteredmodelList.Add(CRM);
}
return View(coursesRegisteredmodelList);
}
And here is the view on which i am trying to display registered courses:
#model StudentRegistrationPortal.Models.CourseRegisterModel
#{
ViewBag.Title = "Welcome Student";
}
<h2>Welcome
#Context.User.Identity.Name
</h2>
#Html.ActionLink("[Sign Out]", "SignOut", "Student")
<ul>
<li>#Html.ActionLink("Register Courses", "registerCourses", "Course")</li>
</ul>
<table>
<tr>
<th>
RollNumber
</th>
<th>
Course Code
</th>
<th>
Course Name
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Context.User.Identity.Name
</td>
<td>
#Html.DisplayFor(modelItem => item)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
</tr>
}
</table>
But foreach loop on above view is giving following compile time error:
foreach statement cannot operate on variables type CourseRegistrationModel beacuse it does not contain a public definition for GetEnumerator
Please help.

Your model needs to be an IEnumerable. See below.
#model IEnumerable<StudentRegistrationPortal.Models.CourseRegisterModel>
#{
ViewBag.Title = "Welcome Student";
}
<h2>Welcome
#Context.User.Identity.Name
</h2>
#Html.ActionLink("[Sign Out]", "SignOut", "Student")
<ul>
<li>#Html.ActionLink("Register Courses", "registerCourses", "Course")</li>
</ul>
<table>
<tr>
<th>
RollNumber
</th>
<th>
Course Code
</th>
<th>
Course Name
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Context.User.Identity.Name
</td>
<td>
#Html.DisplayFor(modelItem => item)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
</tr>
}
</table>
You were trying to do
foreach(CourseRegisterModel item in CourseRegisterModel)
{
...
}
which is not possible, you want.
foreach(CourseRegisterModel item in IEnumerable<CourseRegisterModel>)
{
...
}

You need to make your Model a List or IEnumerable. You simply pass down the class which does not implement GetEnumerator, it should be:
#model IEnumerable<StudentRegistrationPortal.Models.CourseRegisterModel>
Or:
#model List<StudentRegistrationPortal.Models.CourseRegisterModel>

Your view model is a single object as shown here:
#model StudentRegistrationPortal.Models.CourseRegisterModel
you may be wanting to iterate over the CoursesList property in your foreach loop:
#foreach (var item in Model.CoursesList) { .... }

Related

how to create links between pages?

public class Libro
{
public string Titolo { get; set; }
public string Autore { get; set; }
public string Editore { get; set; }
public int ISBN { get; set; }
public int Pagine { get; set; }
public decimal Prezzo { get; set; }
public int Quantità { get; set; }
public Libro BuildLibro(string input)
{
Libro result = null;
if (!String.IsNullOrEmpty(input))
{
var inputArray = input.Split('*');
if (inputArray.Length >= 6)
{
result = new Libro();
result.Titolo = inputArray[0];
result.Autore = inputArray[1];
result.Editore = inputArray[2];
if (!string.IsNullOrEmpty(inputArray[3]))
{
int.TryParse(inputArray[3], out int num);
result.ISBN= num;
}
if (!string.IsNullOrEmpty(inputArray[4]))
{
int.TryParse(inputArray[4], out int num);
result.Pagine = num;
}
if (!string.IsNullOrEmpty(inputArray[5]))
{
decimal.TryParse(inputArray[5], out decimal num);
result.Prezzo = num/100;
}
if (!string.IsNullOrEmpty(inputArray[6]))
{
int.TryParse(inputArray[6], out int num);
result.Quantità = num;
}
}
}
return result;
}
}
}
in the Index.cshtml
<table class="table">
<tr>
<th>
Titolo
</th>
<th>
Autore
</th>
<th>
Editore
</th>
<th>
Prezzo(€)
</th>
</tr>
#foreach (var line in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => line.Titolo)
<p> Visualizza la scheda </p>
</td>
<td>
#Html.DisplayFor(modelItem => line.Autore)
</td>
<td>
#Html.DisplayFor(modelItem => line.Editore)
</td>
<td>
#Html.DisplayFor(modelItem => line.Prezzo)
</td>
</tr>
}
</table>
</body>
</html>
I have created a model of a book based on a list of a file.txt in order to display a table with all the books available, their author, publisher and price, now, for each book, I should be able to open a descriptive sheet also containing ISBN , pages and quantities. From paragraph in the html below #Html.DisplayFor(modelItem => line.Titolo) I inserted a link to the About.cshtml, but I don't know what code to write inside and what to write in the controller too?
this is my controller at the moment:
public ActionResult Index()
{
var fileInput = Reader.Read("C:/Users/test/source/repos/Books/Books/App_Data/Libri.txt");
var libriList = new List<Libro>();
if (fileInput != null)
{
for (var i = 1; i < fileInput.Count; i++)
{
var libri = new Libro();
libri = libri.BuildLibro(fileInput[i]);
if (libri != null)
{
libriList.Add(libri);
}
}
}
Session["currentLibriList"] = libriList;
return View(libriList);
}
public ActionResult About(string titoloId)
{
var myFilteredList = new List<Libro>();
if (Session["currentLibriList"] != null)
{
var lookupList = (List<Libro>)(Session["currentLibriList"]);
myFilteredList = (List<Libro>)lookupList.Where(x => x.Titolo == titoloId);
}
return View(myFilteredList);
}
and this is About.cshtml
<html>
<body>
<table class="table">
#foreach (var line in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => line.Titolo)
</td>
<td>
#Html.DisplayFor(modelItem => line.Autore)
</td>
<td>
#Html.DisplayFor(modelItem => line.Editore)
</td>
<td>
#Html.DisplayFor(modelItem => line.Prezzo)<p>€</p>
</td>
<td>
#Html.DisplayFor(modelItem => line.Pagine)
</td>
<td>
#Html.DisplayFor(modelItem => line.Quantità)
</td>
<td>
#Html.DisplayFor(modelItem => line.ISBN)
</td>
</tr>
}
</table>
</body>
</html>
You can use Url.Action helper to send the line.Titolo to your Controller method and get your data:
<td>
<p><a class="btn btn-default" href="#Url.Action("About","Home", new { titoloId = line.Titolo })">#line.Titolo</a></p>
</td>
Your Index method will store the data in a Session variable and then you retrieve this Session in your About method and cast it to the List<Libro> type. Once you get the list, then you can filter it out based on the titolId. Your last step would be to send this filtered list to your About view. You need to build your About view as per your requirement with the filtered data.
public ActionResult About(string titoloId)
{
var myFilteredList= new List<Libro>();
//Get data for titoloId
if (Session["currentLibriList"] != null)
{
var lookupList = (List<Libro>)(Session["currentLibriList"]);
myFilteredList=lookupList.Where(x=>x.Titolo == titoloId);
}
return View(myFilteredList);
}
public ActionResult Index()
{
var fileInput = Reader.Read("C:/Users/test/source/repos/Books/Books/App_Data/Libri.txt");
var libriList = new List<Libro>();
if (fileInput != null)
{
for (var i = 1; i < fileInput.Count; i++)
{
var libri = new Libro();
libri = libri.BuildLibro(fileInput[i]);
if (libri != null)
{
libriList.Add(libri);
}
}
}
//Set your session here
Session["currentLibriList"]=libriList;
return View(libriList);
}

Access variable of one controller from another view in ASP.NET Core MVC

I am trying build a project while self learning but have been stuck in one place.
I have this class Roles:
namespace IC2021.Models
{
public partial class Roles
{
public Roles()
{
Staffs = new HashSet<Staffs>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Staffs> Staffs { get; set; }
}
}
And another called Staffs:
namespace IC2021.Models
{
public partial class Staffs
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Location { get; set; }
public int? RoleId { get; set; }
public string Archived { get; set; }
public virtual Roles Role { get; set; }
}
}
This is my RolesController:
namespace IC2021.Controllers
{
public class RolesController : Controller
{
private readonly ICOctober2021Context _context;
public RolesController(ICOctober2021Context context)
{
_context = context;
}
// GET: Roles
public async Task<IActionResult> Index()
{
return View(await _context.Roles.ToListAsync());
}
public async Task<IActionResult> RolesWithStaffs()
{
var iCOctober2021Context = _context.Roles.Include(s => s.Staffs);
return View(await iCOctober2021Context.ToListAsync());
}
}
}
And finally I'm trying to view it from RolesWithStaffs:
<!-- model declaration -->
#model IEnumerable<IC2021.Models.Roles>
#{
ViewData["Title"] = "RolesWithViewController";
}
<h1>RolesWithViewController</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
Role
</th>
<th>
Staff Name
</th>
<th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.Staffs)
</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>
So here in the view when I tried to access from Staffs, I am not able (for example item.Staffs.FirstName, or anything else from Staffs). Whereas I can do it other way, I mean from staffs view I can access Roles.Name or Id).
Can anyone please help me? Any help will be highly appreciated.
Your view model looks quite unusual, IMHO you can try this
public async Task<IActionResult> RolesWithStaffs()
{
var model= await _context.Set<Staffs>().Include(s => s.Role).ToListAsync();
return View(model);
}
and view
<table class="table">
<thead>
<tr>
<th>
First Name
</th>
<th>
Last Name
</th>
<th>
Role
</th>
<th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(item=> item.FirstName)
</td>
<td>
#Html.DisplayFor(item=> item.LastName)
</td>
<td>
#Html.DisplayFor(item => item.Role.Name)
</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>

dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[ShimbaSchool.Models.EventMessageDepartment]'

Im experiencing an error on trying to fetch data from a db using a list scaffolding. The error and the code is as follow.
My Model:
namespace ShimbaSchool.Models
{
[Table("tblStaff")]
public class Staff
{
[Key]
public int StaffId { get; set; }
[Required]
[DisplayName("Upload Image")]
public string ImagePath { get; set; }
[Required,MinLength(2),DisplayName("Staff Name")]
public string StaffName { get; set; }
[Required,MaxLength(250)]
[DisplayName("Teacher's Subject")]
public string StaffSpecialty { get; set; }
[NotMapped]
public HttpPostedFileBase ImageFile { get; set; }
}
}
My Controller:
namespace ShimbaSchool.Controllers
{
public class StaffController : Controller
{
EventMessageDepartmentContext db = new EventMessageDepartmentContext();
public ActionResult Index()
{
return View(db.StaffTable.ToList());
}
}
}
The View:
#model IEnumerable<ShimbaSchool.Models.Staff>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_MyLayout.cshtml";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.ImagePath)
</th>
<th>
#Html.DisplayNameFor(model => model.StaffName)
</th>
<th>
#Html.DisplayNameFor(model => model.StaffSpecialty)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.ImagePath)
</td>
<td>
#Html.DisplayFor(modelItem => item.StaffName)
</td>
<td>
#Html.DisplayFor(modelItem => item.StaffSpecialty)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.StaffId }) |
#Html.ActionLink("Details", "Details", new { id=item.StaffId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.StaffId })
</td>
</tr>
}
</table>
On executing i get the error:
The model item passed into the dictionary is of type 'System.Collections.Generic.List 1[ShimbaSchool.Models.Staff]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable 1[ShimbaSchool.Models.EventMessageDepartment]'.
Please help me fix this situation and understand the logic so that there is no next time. To add on i used the same model with another controller and its working fine though the view were rendered on different layouts of the same project.
Actually the list you are passing from controller method to view is a List of EventMessageDepartment, not List of Staff. Please check it properly and pass List of Staff from controller method to the view.
If you are ensured that the data you are passing to the view is List<ShimbaSchool.Models.Staff> then please check your Layout.cshtml page. May be there is #model IEnumerable<EventMessageDepartment> is referenced.
Did you try the following?
public ActionResult Index()
{
return View(db.StaffTable.AsEnumerable());
}
First you need to return an IEnumerable version of your model to the list view.
#model IEnumerable<IdentityManager.Models.MerchantDetail>
Second, you need to return a list from the database. I am doing it via SQL Server, so this is code I got working.
public IActionResult Merchant_Boarding_List()
List<MerchantDetail> merchList = new List<MerchantDetail>();
var model = new MerchantDetail();
try
{
using (var con = new SqlConnection(Common.DB_CONNECTION_STRING_BOARDING))
{
con.Open();
using (var command = new SqlCommand("select * from MerchantDetail md where md.UserGUID = '" + UserGUID + "'", con))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
model.biz_dbaBusinessName = reader["biz_dbaBusinessName"].ToString();
merchList.Add(model);
}
}
}
}
}
catch (Exception ex)
{
}
return View(merchList);

Filtering by parameter & Routing

I have an MachineInfo view page which I am showing 60 different specifications of the related machine like processor info, ram info, disk info, db info etc.
ActionLink to this page is:
#Html.ActionLink("Machine Info", "MachineInfo", new { id = Model.LicenseKey }) |
Controller:
public ActionResult MachineInfo(string LicenseKey)
{
if (LicenseKey == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Farm farm = db.Farms.Find(LicenseKey);
if (farm == null)
{
return HttpNotFound();
}
return View(farm);
}
Farm Model:
public partial class Farm
{
public Farm()
{
this.FarmChanges = new HashSet<FarmChange>();
this.FarmDetails = new HashSet<FarmDetail>();
this.FarmTables = new HashSet<FarmTable>();
}
public int Id { get; set; }
public string LicenseKey { get; set; }
public string Name { get; set; }
public string CustomerName { get; set; }
public virtual ICollection<FarmChange> FarmChanges { get; set; }
public virtual ICollection<FarmDetail> FarmDetails { get; set; }
public virtual ICollection<FarmTable> FarmTables { get; set; }
}
FarmDetails Model:
public partial class FarmDetail
{
public System.Guid Id { get; set; }
public int FarmId { get; set; }
public int Type { get; set; }
public string Name { get; set; }
public string Value { get; set; }
public virtual Farm Farm { get; set; }
}
All the MachineInfo is coming from the "Value" in the FarmDetails table.
View:
#model IEnumerable<FarmManagement.Models.FarmDetail>
#{
ViewBag.Title = "Machine Info";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Machine Info</h2>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Type)
</th>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Value)
</th>
<th>
#Html.DisplayNameFor(model => model.Farm.LicenseKey)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Type)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Value)
</td>
<td>
#Html.DisplayFor(modelItem => item.Farm.LicenseKey)
</td>
<td>
</td>
</tr>
}
</table>
#Html.ActionLink("Back to Farms List", "Index")
I am trying to show MachineInfo of a specific machine (LicenseKey=ABXYZ-XYZAB) with this url: mydomain.com/MachineInfo/ABXYZ-XYZAB
I need to filter the view by LicenseKey.
After my all tries, I'm only getting 400 - Bad Request error (Because LicenseKey == null) or getting the MachineInfo of ALL machines, not the specific machine with LicenseKey=ABXYZ-XYZAB.
What I am doing wrong?
Change your actionlink code
#Html.ActionLink("Machine Info", "MachineInfo", new { id = Model.LicenseKey })
to
#Html.ActionLink("Machine Info", "MachineInfo", new { LicenseKey = Model.LicenseKey })
As the Action link parameter name should match with the controller action parameter name.
Solved the problem after making following changes:
New Controller After Change:
public ActionResult MachineInfo(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
FarmDetail farmdetail = db.FarmDetails.Where(x => x.FarmId == id).FirstOrDefault();
if (farmdetail == null)
{
return HttpNotFound();
}
return View(farmdetail);
}
New View After Change:
#model FarmManagement.Models.FarmDetail
#{
ViewBag.Title = "Machine Info";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Machine Info</h2>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Type)
</th>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Value)
</th>
<th>
#Html.DisplayNameFor(model => model.Farm.LicenseKey)
</th>
<th></th>
</tr>
#for (int i = 0; i < Model.Farm.FarmDetails.Count(); i++)
{
<tr>
<td>
#Html.DisplayFor(model => model.Farm.FarmDetails.ElementAt(i).Type)
</td>
<td>
#Html.DisplayFor(model => model.Farm.FarmDetails.ElementAt(i).Name)
</td>
<td>
#Html.DisplayFor(model => model.Farm.FarmDetails.ElementAt(i).Value)
</td>
<td>
#Html.DisplayFor(model => model.Farm.LicenseKey)
</td>
<td>
</tr>
}
</table>
#Html.ActionLink("Back to Farms List", "Index")
I needed to use a where sentence in Controller;
FarmDetail farmdetail = db.FarmDetails.Where(x => x.FarmId == id).FirstOrDefault();
And removed IEnumerable from the View and changed #foreach to #for with ElementAt(i).
#Html.DisplayFor(model => model.Farm.FarmDetails.ElementAt(i).Name)

How do I add a "model" dropdown in a IPagedlist model?

I have a page to display every log (message, time, type, customerId, Name) in a html table. Since the log is huge I am using a IPagedList in the Razor MVC and this works perfectly. I currently have 2 search boxes (for admins) and 1 for members. Where you can search by the message and customer ID.
Now the problem is that I don't want the users to just have a textbox where you only can put in a number (for example you put in customer ID 2 and get the customer T) - but instead I want a dropdown with all the current customer names connected to the customer IDs.
I have this functionality in another page I use but it only works because I return the model on the other page and because the log page returns a "IPagedListModel" instead of a "Model" I can't use this solution. How would I make this solution work for my log page as well?
HTML code
#:<p>#Html.DropDownListFor(m => m.SelectedCustomer, Model.CustomerList)</p>
Model
using System;
using System.Linq;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Collections.Generic;
using PagedList;
using System.Web.Mvc;
namespace ASDMVC.Models
{
[Table("Log")]
public class LogModel
{
[Key]
public long id { get; set; }
public string message { get; set; }
public DateTime timeStamp { get; set; }
public string level { get; set; }
public int customerId { get; set; }
[NotMapped]
public string Name { get; set; }
}
public class LogModelVM
{
public int SelectedCustomer { get; set; }
public IEnumerable<SelectListItem> CustomerList { get; set; }
public string Message { get; set; }
public IPagedList<LogModel> Logs { get; set; }
}
public class LogDBContext:DbContext
{
public LogDBContext() : base("MySqlConnection")
{
}
public DbSet <LogModel> Log { get; set; }
public IQueryable<LogModel> GetLogs()
{
return from log in Log
select log;
}
}
}
Controller
public class DbCustomerIds
{
public List<DbCustomer> GetCustomerIds()
{
List<DbCustomer> Customers = new List<DbCustomer>();
string queryString = "SELECT * FROM dbo.customers";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, System.Configuration.ConfigurationManager.ConnectionStrings["MySqlConnection"].ConnectionString);
DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");
foreach (DataRow item in customers.Tables[0].Rows)
{
DbCustomer cid = new DbCustomer();
cid.FakeId = Convert.ToInt32(item["Id"]);
cid.FakeName = Convert.ToString(item["Name"]);
Customers.Add(cid);
}
return Customers;
}
}
private IEnumerable<SelectListItem> GetCustomerIds()
{
var DbCustomerIds = new DbCustomerIds();
var customers = DbCustomerIds
.GetCustomerIds()
.Select(x =>
new SelectListItem
{
Value = x.FakeId.ToString(),
Text = x.FakeName
});
return new SelectList(customers, "Value", "Text");
}
}
[HttpPost]
public PartialViewResult LogPartialView(string searchString, string searchString2, string currentFilter, string currentFilterz, int? page, string sortOrder)
{
if (Roles.IsUserInRole(WebSecurity.CurrentUserName, "Admin"))
{
Customer = GetCustomerIds();
message = db.GetLogs();
int pageSize = 10;
int pageNumber = (page ?? 1);
var logs = message.OrderByDescending(i => i.timeStamp).ToPagedList(pageNumber, pageSize);
foreach (var log in logs)
log.Name = Customer.Where(a => a.Value == log.customerId.ToString()).FirstOrDefault().Text;
LogModelVM LMVM = new LogModelVM();
LMVM.Logs = logs;
LMVM.CustomerList = Customer;
return PartialView("_LogPartialLayout", LMVM);
}
LogModelVM LMVM = new LogModelVM();
LMVM.Logs = logs;
LMVM.CustomerList = Customer;
return PartialView("_LogPartialLayout", LMVM);
}
_LogPartialLayout
#model ASDMVC.Models.LogModelVM
#using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#if (Roles.IsUserInRole(WebSecurity.CurrentUserName, "Admin"))
{
<table class="table">
<tr>
<th id="tableth">
message
</th>
<th id="tableth">
timestamp
</th>
<th id="tableth">
level
</th>
<th id="tableth">
customerId
</th>
<th id="tableth">
customerName
</th>
</tr>
#foreach (var item in Model.Logs)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.message)
</td>
<td>
#Html.DisplayFor(modelItem => item.timeStamp)
</td>
<td>
#Html.DisplayFor(modelItem => item.level)
</td>
<td>
#Html.DisplayFor(modelItem => item.customerId)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
</tr>
}
</table>
}
#if (Roles.IsUserInRole(WebSecurity.CurrentUserName, "Member"))
{
<table class="table">
<tr>
<th id="tableth">
message
</th>
<th id="tableth">
timestamp
</th>
<th id="tableth">
level
</th>
</tr>
#foreach (var item in Model.Logs)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.message)
</td>
<td>
#Html.DisplayFor(modelItem => item.timeStamp)
</td>
<td>
#Html.DisplayFor(modelItem => item.level)
</td>
</tr>
}
</table>
}
Page #(Model.Logs.PageCount < Model.Logs.PageNumber ? 0 : Model.Logs.PageNumber) of #Model.Logs.PageCount
#Html.PagedListPager(Model.Logs, page => Url.Action("LogPartialView",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, currentFilterz = ViewBag.CurrentFilterz }), PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(PagedListRenderOptions.ClassicPlusFirstAndLast,
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "divLogs"
}))
Any help would be apprechiated, sorry for the long question - I just wanted to get all the information which seems relevant to the situation.
Thanks in advance.
Current error when running:
[InvalidOperationException: The model item passed into the dictionary is of type 'PagedList.PagedList`1[NowasteWebPortalMVC.Models.LogModel]', but this dictionary requires a model item of type 'NowasteWebPortalMVC.Models.LogModelVM'.]
Create a view model with the properties you need in the view
public class LogModelVM
{
public int SelectedCustomer { get; set; }
public IEnumerable<SelectListItem> CustomerList { get; set; } // suggested name change
public string Message { get; set; } // for the message search box?
public IPagedList<NowasteWebPortalMVC.Models.LogModel> Logs { get; set; }
.... // add properties for sortorder etc
}
Then in the controller method, initiaize a new LogModelVM and assign the values (e.g. model.Logs = logs;), and return the view model so that in the view you can use
#model yourAssembly.LogModelVM
....
#Html.DropDownListFor(m => m.SelectedCustomer, Model.CustomerList) // why change the id attribute?
....
#Html.PagedListPager(Model.Logs, page => Url.Action(...`
You should also consider adding the other properties such as sortOrder and currentfilter rather than using ViewBag
Side note: Ensure that all associated views, including the main view also use #model yourAssembly.LogModelVM

Categories