0

I'am trying to view information from two tables in a view with the view model, but it does not work.

This gives two tables with information.

public class HeatImage
{
    [Key]
    public int ImageId { get; set; }
    public string name { get; set; }
}

public class HeatingArea
{
    [Key]
    public int ID  { get; set; }
    public string Area { get; set; } 

}

My viewmodel

public class HeatingAreaViewModel
{
    public IEnumerable<HeatImage> heatingImage { get; set; }
    public IEnumerable<HeatingArea> heatingArea { get; set; }
}

My controller

  public ActionResult Index()
        {
            HeatingAreaViewModel mymodel = new HeatingAreaViewModel();
            mymodel.heatingArea = db.HeatingAreas.ToList();
            mymodel.heatingImage = db.HeatImages.ToList();

            return View(mymodel);
        }

And my view

@model IEnumerable<Project.Models.HeatingAreaViewModel>
 @foreach (var item in Model)
            {
                <a href="~/folder/@item.heatingImage">@item.heatingArea</a>
            }

Error

The model item passed into the dictionary is of type 'Project.Models.HeatingAreaViewModel', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[Project.Models.HeatingAreaViewModel]'.

Xtreme
  • 1,601
  • 7
  • 27
  • 59

5 Answers5

1

The error message tells it: the View expects IEnumerable of HeatingAreaViewModel, while your controller action sends to the view only HeatingAreaViewModel.

So either correct the controller to send a list of HeatingAreaViewModel, or correct the view to expect only a single instance of HeatingAreaViewModel.

Dano
  • 234
  • 1
  • 5
  • How can I change my controller? – Xtreme Nov 15 '15 at 22:50
  • @Xtreme, You don't change the controller, you change the view to `model Project.Models.HeatingAreaViewModel` and then `@foreach (var item in Model.heatingImage)` and/or `@foreach (var item in Model.heatingArea)` –  Nov 16 '15 at 00:18
1

You are sending through appels and expecting oranges, that is why you getting the error.

In your controller you are sending through a single (one) instance of HeatingAreaViewModel. In your view you are making provision to except a list of HeatingAreaViewModel instances (more than 1).

Reading through your replies you want to use both HeatImage and HeatingArea in each loop iteration. You will need to change your view model to accommodate this. For example, create a view model that can accommodate both:

public class HeatViewModel
{
     public HeatImage HeatImage { get; set; }

     public HeatingArea HeatingArea { get; set; }
}

You will pass this HeatViewModel as a list to your view.

public ActionResult Index()
{
     // This is just dummy code
     HeatingViewModel model1 = new HeatingAreaViewModel();
     // Populate the properties
     model1.HeatImage = new HeatImage();
     // Populate the properties
     model1.HeatingArea = new HeatingArea();

     HeatingViewModel model2 = new HeatingAreaViewModel();
     // Populate the properties
     model2.HeatImage = new HeatImage();
     // Populate the properties
     model2.HeatingArea = new HeatingArea();

     // Now pass this list to the view
     List<HeatingViewModel> models = new List<HeatingViewModel>();

     return View(models);
}

In your view your code would look something like this:

@model List<Project.Models.HeatingViewModel>
@foreach (var item in Model)
{
     <p>item.HeatImage.Name</p>
     <p>item.HeatingArea.ID (I have used ID because I don't know what your Area looks like)</p>
}

This way you have both objects in a single loop. You will just have to go and figure out how you are going to populate them, this is where the bulk of the work will be done.

I also noticed that you you start your properties in the lower case, best practices start them with caps. For example:

public HeatImage heatImage { get; set; }

...should be...

public HeatImage HeatImage { get; set; }

I hope this helps :)

Brendan Vogt
  • 25,678
  • 37
  • 146
  • 234
0

Your view is expecting an IEnumerable of HeatingAreaViewModel and it seems as though your only passing a single instance.

Change this

@model IEnumerable<Project.Models.HeatingAreaViewModel>

to this

@model Project.Models.HeatingAreaViewModel

Then you'll be able to loop through the heatingArea and heatingImage properties like this

@foreach (var item in model.heatingArea)
{
    //what ever you need to do here
}
matt.
  • 2,355
  • 5
  • 32
  • 43
  • Thanks, but how can I get both heatingArea and heatingImage in the same loop? I want to create this link `@item.heatingArea` – Xtreme Nov 15 '15 at 22:50
  • 1
    I'm not sure you can iterate over two IEnumerables in one loop. Can you explain what exactly you're trying to do? `heatingImage` and `heatingArea` are two separate lists. – matt. Nov 15 '15 at 23:04
  • @Xtreme, oh, so you're trying to solve a different problem, how to put two lists together, not how to display it in an MVC view, I'm going to write a second answer, see that one for a solution and further comments. – Dano Nov 16 '15 at 08:06
0

If your problem is, how to iterate in one loop through the two lists of HeatingImage and HeatingArea, in your view, you have to redo your viewModel:

public class HeatingAreaViewModel
{
    public HeatImage heatingImage { get; set; }
    public HeatingArea heatingArea { get; set; }
}

and then the controller action:

    public ActionResult Index()
            {
                heatingAreas = db.HeatingAreas.ToList();
                heatingImages = db.HeatImages.ToList();

                List<HeatingAreaViewModel> myModel = heatingAreas.Zip(heatingImages, (a, b) => new HeatingAreaViewModel {HeatingArea = a, HeatImage = b})

                return View(mymodel);
            }

Then the View will work, as it is.

However, I strongly advice against doing it this way. You would have to ensure, that corresponding elements in the two lists are in reality corresponding to each other. Which is very prone to errors. If there is an underlying logic that ties these two lists together (some relationship on database tables), I would use that one to join the lists/tables together, instead.

Dano
  • 234
  • 1
  • 5
0

Simply your Model in the view doesn't matches what you sent from controller action, so I think you need to change your view to be like this:

@model HeatingAreaViewModel
@foreach (var item in Model.heatingImage)
{
   <a href="~/folder/@item.heatingImage">@item.heatingArea</a>
}
Mahmoud Hboubati
  • 1,007
  • 11
  • 26