0

I am new to Entity and Visual Studio. I have two models already populated with data and the third one is originally part of the controller that I want to implement the other two models in. I don't want to edit the other two models but just show the data already in the table.

I have tried using tuple using this tutorial Multiple models in a view but am unable to use @foreach statements.

@model Tuple<App.Models.ValueForecast, App.Models.FacilityEditor, App.Models.ForecastSub>

Whats the easiest way of being able to have three models in one view? The other two models must be able to display the data from their table data.

I know there is a method with a viewModels but the data from the table is not showing up, I used this method: Two models in one view in ASP MVC 3 but did not work

Community
  • 1
  • 1
johndoesnow
  • 33
  • 1
  • 8
  • You can't @foreach a tuple, but if one of the properties of the tuple implements IEnumerable, you can. Is that the case? Which type of the listed tuple does? –  Aug 30 '16 at 18:38
  • @Will, yup understood, I saw that in other stackoverflow pages but then how else would I do it? – johndoesnow Aug 30 '16 at 18:39
  • Why doesn't the linked answer work for you? How did you implement that solution? – Jasen Aug 30 '16 at 18:42
  • I see no problem here. You say you can't `@foreach` something, but you haven't told us exactly ***what*** you want to `@foreach`. It's a bit of a problem, trying to help you. –  Aug 30 '16 at 18:43
  • @Will I'm trying to display all the properties in all the models. Thats why I wanted to use a foreach so each instance would show up – johndoesnow Aug 30 '16 at 19:00
  • 1
    Foreach only works for IEnumerables. What implements IEnumerable here? –  Aug 30 '16 at 19:09

2 Answers2

3

Just create an object to transfer the data, you need to distinguish between your domain model (Where the logic of the problem should reside), you data model (Normally the ones that are mapped to databases and stuff), and your Data Transfer Objects (which are the who only reason to live is to encapsulate you objects to be passed between methods).

You need a DTO when you are passing too many parameters to one method, or when you need several objects in your views (talking about c# and web development) DTOs.

Even in the new c# core and his web development part, many people recommend to have a folder called "ViewModels" where you can place one view model per view, allowing to pass complex objects.

Other link to clarify: What are view models?

A view model represents the data that you want to display on your view/page, whether it be used for static text or for input values (like textboxes and dropdown lists) that can be added to the database (or edited). It is something different than your domain model. It is a model for the view.

So, you should create a new class that act as a container of your other objects, in your case something like:

public class NameOfTheviewViewModel {
    public App.Models.ValueForecast ValueForecast { get; set; }
    public App.Models.FacilityEditor FacilityEditor { get; set; }
    public App.Models.ForecastSub ForecastSub { get; set; }
}

And then use this class as the model for your view:

@model NameOfTheviewViewModel
foreach(var item in Model.ValueForecast) //Or whatever your list are
{
     // do something
}
Community
  • 1
  • 1
rekiem87
  • 1,565
  • 18
  • 33
  • Should I use tuple or continue with just "@model IEnumerable" – johndoesnow Aug 30 '16 at 18:41
  • @johndoesnow you need to create a class to hold your data, not a tuple. You can then just use this View Model class when dealing with your data. – lukejkw Aug 30 '16 at 18:56
  • @rekiem87 I created a separate class exactly how u did it and put it in a folder called ViewModel then did: model RogersExcel.ViewModel.ValueForecastModels, when I use foreach (var item in Model.valueForecast) , I get an error: CS1579: foreach statement cannot operate on variables of type 'App.Models.ValueForecast' because 'App.Models.ValueForecast' does not contain a public definition for 'GetEnumerator' – johndoesnow Aug 30 '16 at 19:11
  • @rekiem87 I keep getting a GetEnumerator error when trying to run foreach statement – johndoesnow Aug 30 '16 at 19:18
  • @rekiem87 when I delete that statement I get this error: The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[App.Models.ValueForecast]', but this dictionary requires a model item of type 'App.ViewModel.ValueForecastModels'. – johndoesnow Aug 30 '16 at 19:23
  • If you update your question with some code snippets, like your models, view and the controller that is trying to render that view we could help better – rekiem87 Aug 31 '16 at 13:52
  • Why you need the foreach?, do you really have a collection? (anything IEnumerable), the error is quite clear, you are trying to do a foreach in an object that is not a collection – rekiem87 Aug 31 '16 at 13:54
0

Just create a class (view model) to hold the data that your need and map your 3 different domain class's data to it (this could be done manually or with something like AutoMapper). You will then just declare this view model as the model for your view.

Please note that mapping your domain objects (POCOs) straight to your View is not ideal as you often end up mixing presentation specific code in with your data access layer code.

Separate these concerns into a Data layer with all your POCOs and a presentation layer. Then, when you need to display this data, create a ViewModel to represent/transfer this data between your view and your controller. It is a little more code but is well worth it in my opinion.

lukejkw
  • 1,054
  • 13
  • 19