0

learning to work around c# and razor. I have this issue which I am struggling to get my head around. I have researched this forum to understand but to no avail. The model item is of type CookMeIndexViewModel, but requires a model item of type IEnumerable<CookMeIndexViewModel>

Anyway this is the code I have been working with: However my data are coming from my VehicleClass. My VehicleClass

using LogViewer.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace LogViewer.Classes
{
    public class VehicleClass
    {
        public int id { get; set; }
        public String make { get; set; }
        public String type { get; set; }
        public byte taxBand { get; set; }
        public DateTime created { get; set; }
        public DateTime updated { get; set; }
        public DateTime deleted { get; set; }
        public bool isDeleted { get; set; }
        public decimal price { get; set; }
        public String description { get; set; }

        public List<Vehicles> _VehicleList = new List<Vehicles>();

        public VehicleClass()
        {
            _VehicleList.Add(new Vehicles
            {
                id = 001,
                make = "Renault",
                type = "Saloon",
                taxBand = 5,
                created = new DateTime(2015,1,1),
                updated = new DateTime(2015,3,1),
                deleted = DateTime.Now,
                isDeleted = true,
                price = 3000,
                description = "A very comfortable car to ride"
            });

            _VehicleList.Add(new Vehicles
            {
                id = 002,
                make = "Toyota",
                type = "Hatchback",
                taxBand = 2,
                created = new DateTime(2015,2,1),
                updated = new DateTime(2015,3,9),
                deleted = DateTime.Now,
                isDeleted = true,
                price = 2500,
                description = "Reliable, strong, fuel efficient"
            });

            _VehicleList.Add(new Vehicles
            {
                id = 003,
                make = "Audi",
                type= "Saloon",
                taxBand = 6,
                created = new DateTime(2015,4,3),
                updated = new DateTime(2015,6,1),
                deleted = DateTime.Now,
                isDeleted = true,
                price = 6000,
                description = "A high performance car"
            });
        }
    }
}

Controller Class: HomeController.cs

using LogViewer.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace LogViewer.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index(string sortOrder)
        {
            VehicleClass _vehicles = new VehicleClass();
            ViewBag.IdSortParam = String.IsNullOrEmpty(sortOrder) ? "id_desc" : "";
            ViewBag.MakeSortParam = sortOrder == "Make" ? "make_desc" : "Make";

            switch(sortOrder)
            {
                case "id_desc":
                    _vehicles._VehicleList.OrderByDescending(v => v.id).ToList();
                    break;

                case "make_desc":
                    _vehicles._VehicleList.OrderByDescending(v => v.id).ToList();
                    break;

                default:
                    break;
            }
            return View(_vehicles._VehicleList.ToList());
        }
    }
}

Finally my View: Index.cshtml

@model LogViewer.Classes.VehicleClass

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<table>
    <thead>
        <tr>
            <th>
                @Html.ActionLink("ID", "Index", new { sortOrder = ViewBag.IdSortParam, currentFilter = ViewBag.CurrentFilter})
            </th>
            <th>
                @Html.ActionLink("Make", "Index", new { sortOrder = ViewBag.MakeSortParam, currentFilter = ViewBag.CurrentFilter})
            </th>
            <th>Type</th>
            <th>Tax Band</th>
            <th>Created</th>
            <th>Updated</th>
            <th>Deleted</th>
            <th>Is Deleted</th>
            <th>Price</th>
            <th>Description</th>
        </tr>
    </thead>
</table>

@foreach (var item in Model._VehicleList)
{
<table>
    <tbody>
        <tr>
            <td>@item.id</td>
            <td>@item.make</td>
            <td>@item.type</td>
            <td>@item.taxBand</td>
            <td>@item.created</td>
            <td>@item.updated</td>
            <td>@item.deleted</td>
            <td>@item.isDeleted</td>
            <td>@item.price</td>
            <td>@item.description</td>
        </tr>
    </tbody>
</table>
}

The error I have been receiving is this:

The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[LogViewer.Models.Vehicles]', but this dictionary requires a model item of type 'LogViewer.Classes.VehicleClass'.

Community
  • 1
  • 1
Yuvi
  • 528
  • 8
  • 18
  • 1
    Too much code, cut out irrelevant parts. But i guess that you are passing list to dictionary, when you should pass VehicleClass – FINDarkside Jun 29 '15 at 11:19
  • 1
    should be `return View(_vehicles);` in your `Index` action – Mike Debela Jun 29 '15 at 11:25
  • Regarding passing the objects, I had previously had return View (_vehicles); however my sorting functions didn't do any sorting. Maybe there is an issue with my sorting logic which I cant seem to see where. – Yuvi Jun 29 '15 at 11:28

3 Answers3

0

change in your view (cshtml file) to->

@model List<LogViewer.Classes.VehicleClass>
Kram
  • 526
  • 5
  • 11
  • Thanks I made those changes without making any changes in the controller class however I got a compilation error: { Line 30: Line 31: Line 32: @foreach (var item in Model._VehicleList) Line 33: { Line 34: }
    – Yuvi Jun 29 '15 at 11:31
  • can you attach the internal exception? – Kram Jun 29 '15 at 12:07
0

In your Index.cshtml replace your model with this:

@model IEnumerable<LogViewer.Classes.VehicleClass>

You are returning a _vehicles._VehicleList.ToList() model wich is a list while your View accepts only one instance of the class.

EDIT

Your <table> should be outside the Index.cshtml foreach loop:

This:

    </tr>
    </thead>
</table>

@foreach (var item in Model._VehicleList)
{
<table>
    <tbody>
        <tr>

Should be switched to this:

       </tr>
    </thead>
    <tbody>
@foreach (var item in Model._VehicleList)
{
         <tr>
Damiano C.
  • 282
  • 1
  • 9
0

Since you have this in your view

@model LogViewer.Classes.VehicleClass

You should pass an instance of VehicleClass to your view instead of List<Vehicles>, so change this in your controller

return View(_vehicles._VehicleList.ToList());

to this

return View(_vehicles);

EDIT

Based on the question comments, you said that the sorting didn't work. That's because you're not doing any sorting in the controller. Please have a look at the following lines of code in your controller

switch(sortOrder)
{
    case "id_desc":
        _vehicles._VehicleList.OrderByDescending(v => v.id).ToList();
        break;

    case "make_desc":
        _vehicles._VehicleList.OrderByDescending(v => v.id).ToList();
        break;

    default:
        break;
}

Doing this

_vehicles._VehicleList.OrderByDescending(v => v.id).ToList(); 

won't change the order of the items in _vehicles._VehicleList. You need to assign the ordered list back to _vehicles._VehicleList like this

_vehicles._VehicleList = _vehicles._VehicleList.OrderByDescending(v => v.id).ToList();

Additionally, it seems that if the value of sortOrder is "make_desc", the items should be ordered by a different property. I guess the property would be make, so your controller should be modified as below

public ActionResult Index(string sortOrder)
{
    VehicleClass _vehicles = new VehicleClass();
    ViewBag.IdSortParam = String.IsNullOrEmpty(sortOrder) ? "id_desc" : "";
    ViewBag.MakeSortParam = sortOrder == "Make" ? "make_desc" : "Make";

    switch(sortOrder)
    {
        case "id_desc":
            _vehicles._VehicleList = _vehicles._VehicleList.OrderByDescending(v => v.id).ToList();
            break;

        case "make_desc":
            _vehicles._VehicleList = _vehicles._VehicleList.OrderByDescending(v => v.make).ToList();
            break;

        default:
            break;
    }
    return View(_vehicles);
}
ekad
  • 14,436
  • 26
  • 44
  • 46
  • This wouldn' t work either, the Index.cshtml iterates on a collection of VehicleClass instances – Damiano C. Jun 29 '15 at 11:38
  • @DamianoC, this would work, the syntax in the view is `@foreach (var item in Model._VehicleList)`, so it will enumerate the items in `Model._VehicleList`, which is a collection of `Vehicles`. – ekad Jun 29 '15 at 11:45
  • Right I hadn' t seen the class properties – Damiano C. Jun 29 '15 at 11:53
  • Thank you ekad and Damiano. I have managed to make it work however my codes has been totally changed since the start. Also I never realized that with case 2 that the sorting was still done by .id instead of make. – Yuvi Jun 29 '15 at 12:16
  • Thank you. I really welcome your comment. As my understanding, toList() actually creates a new list in the memory and then replaces the previous list. Is that why you assign? Again I will look into the msdn for further research. – Yuvi Jun 30 '15 at 08:47
  • `ToList()` does create a new list in memory, but it doesn't replace the previous list, so that's why you need to assign it back to the same list or another list. Have a look at this fiddle: https://dotnetfiddle.net/zosQuf, it demonstrates the difference between when it's assigned and it's not assigned. Here's the [MSDN link](https://msdn.microsoft.com/en-us/library/vstudio/bb342261%28v=vs.100%29.aspx) for reference. – ekad Jun 30 '15 at 09:05