Multiple Models in Single View in ASP.NET MVC

Hi experts,

I saw the following example:

Multiple Models in Single View in MVC
http://www.c-sharpcorner.com/uploadfile/ff2f08/multiple-models-in-single-view-in-mvc/

In this example they are using ASP.NET MVC, C#, Razor and the code download link is a Visual Studio 2010 project.

So I decided to redo the example using Visual Studio 2013 and MVC 5.


Example 1

My Visual Studio 2013 app directory looks like this:

app directory
This is my code:

Controller

Model

MyModels.cs

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

namespace SampleApp.Models
{
    public class Teacher
    {
        public int TeacherId { get; set; }
        public string Code { get; set; }
        public string Name { get; set; }
    }

    public class Student
    {
        public int StudentId { get; set; }
        public string Code { get; set; }
        public string Name { get; set; }
        public string EnrollmentNo { get; set; }
    }

    public class ViewModel
    {
        public IEnumerable<Teacher> Teachers { get; set; }
        public IEnumerable<Student> Students { get; set; }
    }
}

Open in new window



Controller

HomeController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SampleApp.Models;

namespace SampleApp.Controllers
{
    public class HomeController : Controller
    {

        // Multiple Model in single view using View Model
        // GET: Home
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to my demo!";
            ViewModel mymodel = new ViewModel();
            mymodel.Teachers = GetTeachers();
            mymodel.Students = GetStudents();
            return View(mymodel);
        }
        
        public List<Teacher> GetTeachers()
        {
            List<Teacher> teachers = new List<Teacher>();
            teachers.Add(new Teacher { TeacherId = 1, Code = "TT", Name = "Tejas Trivedi" });
            teachers.Add(new Teacher { TeacherId = 2, Code = "JT", Name = "Jignesh Trivedi" });
            teachers.Add(new Teacher { TeacherId = 3, Code = "RT", Name = "Rakesh Trivedi" });
            return teachers;
        }

        public List<Student> GetStudents()
        {
            List<Student> students = new List<Student>();
            students.Add(new Student { StudentId = 1, Code = "L0001", Name = "Amit Gupta", EnrollmentNo = "201404150001" });
            students.Add(new Student { StudentId = 2, Code = "L0002", Name = "Chetan Gujjar", EnrollmentNo = "201404150002" });
            students.Add(new Student { StudentId = 3, Code = "L0003", Name = "Bhavin Patel", EnrollmentNo = "201404150003" });
            return students;
        }
        
    }
}

Open in new window


View

Home/Index.cshtml

@using SampleApp.Models;
@model ViewModel
@{
    ViewBag.Title = "Index";
}
<h2>@ViewBag.Message</h2>

<p><b>Teacher List</b></p>

<table>
    <tr>
        <th>Id</th>
        <th>Code</th>
        <th>Name</th>
    </tr>
    @foreach (Teacher teacher in Model.Teachers)
    {
        <tr>
            <td>@teacher.TeacherId</td>
            <td>@teacher.Code</td>
            <td>@teacher.Name</td>
        </tr>
    }
</table>

<p><b>Student List</b></p>

<table>
    <tr>
        <th>Id</th>
        <th>Code</th>
        <th>Name</th>
        <th>Enrollment No</th>
    </tr>
    @foreach (Student student in Model.Students)
    {
        <tr>
            <td>@student.StudentId</td>
            <td>@student.Code</td>
            <td>@student.Name</td>
            <td>@student.EnrollmentNo</td>
        </tr>
    }
</table>

Open in new window


If you notice in the code above, this example is using a static list of teachers and students which are declared in the controller.
So when I run my application above code it runs just fine and it looks like this:

when i run this page

So now I wanted to create another similar example using this same View Model technique.


Example 2

In example 2 instead of using a static list of teachers and students likes was done in Example 1
I am going to instead use the Employees table from the Northwind Sql Server database and the Department table of the AdventureWorks Sql Server database.

So my directory looks like this:

Example 2 application directory
Northwind Employees table looks like this:

Northwind Employees table
Adventureworks Department table looks like this:

Department table

My model for Northwind.edmx looks like this:

Northwind model
My model for Adventureworks.edmx looks like this:

Adventureworks model

Model

MyModel.cs

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

namespace NorthwindApp.Models
{
    public class ViewModel
    {
        // Northwind - Employees
        public IEnumerable<Employee> Employees { get; set; }

        // AdventureWorks - Department
        public IEnumerable<Department> Departments { get; set; }
    }
}

Open in new window


Controller

HomeController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using NorthwindApp.Models;

namespace NorthwindApp.Controllers
{
    public class HomeController : Controller
    {
        // Multiple Model in single view using View Model
        // private NorthwindEntities db1 = new NorthwindEntities();

        // GET: Home
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to my demo!";
            ViewModel mymodel = new ViewModel();

            // Northwind - Employees
            // create a list of teachers and pass it to model
            //mymodel.Teachers = GetTeachers();
            //db1.Customers.ToList();
            mymodel.Employees.ToList();

            // AdventureWorks - Department
            // create a list of students and pass it to model
            //mymodel.Students = GetStudents();
            //db1.Department.ToList();
            mymodel.Departments.ToList();

            return View(mymodel);
        }
    }
}

Open in new window



View

Home/Index.cshtml

@using NorthwindApp.Models;
@model ViewModel

@{
    ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>

<p><b>Northwind - Employees List</b></p>

<table>
    <tr>
        <th>EmployeeID</th>
        <th>LastName</th>
        <th>FirstName</th>
    </tr>   
    @foreach (Employee employee in Model.Employees)
    {
        <tr>
            <td>@employee.EmployeeID</td>
            <td>@employee.LastName</td>
            <td>@employee.FirstName</td>
        </tr>
    }
</table>

<p><b>AdventureWorks - Department List</b></p>

<table>
    <tr>
        <th>Id</th>
        <th>Code</th>
        <th>Name</th>
        <th>Enrollment No</th>
    </tr>
    @foreach (Department department in Model.Departments)
    {
        <tr>
            <td>@department.DepartmentID</td>
            <td>@department.Name</td>
            <td>@department.GroupName</td>
        </tr>
    }
</table>

Open in new window



When I run my page though I'm getting this error on my controller.

the error I'm getting in my controller
I think I'm not passing my Employe List and Department list correctly to my View.

Anyone know the correct syntax i should be using?

Normally when I want to pass a list from controller to my view i declare my entity like this

private NorthwindEntities db = new NorthwindEntities ();

Then in my actionresult i would pass one list like this.

        // GET: Home
        public ActionResult Index()
        {
            return View(db.Employees.ToList());
        }

But in example 2 above i'm trying to pass 2 lists to my view.

Anyone know what i'm doing wrong?
LVL 1
maqskywalkerAsked:
Who is Participating?
 
Miguel OzSoftware EngineerCommented:
Kaufmed's post is not correct because a default constructor will provide empty lists not the ones loaded from DB
You need to instantiate both properties to be consumed by your View. If they are coming from database you should load the properties from the associated DB context as shown below:
//Let's assume your context classes are named NorthwindEntities and AdventureWorksEntities  
private NorthwindEntities db = new NorthwindEntities ();
private AdventureWorksEntities awdb = new AdventureWorksEntities ();

public ActionResult Index()
        {
            ViewBag.Message = "Welcome to my demo!";
            ViewModel mymodel = new ViewModel();
            // Northwind - Employees
           mymodel.Employees = db.Employees.ToList());

            // AdventureWorks - Department
            mymodel.Departments = awdb.Departments .ToList());;

            return View(mymodel);
        }

Open in new window

0
 
käµfm³d 👽Commented:
This has nothing to do with what you're passing. The problem is that, while you instantiated your ViewModel, you did not instantiate the Employees member that belongs to that class. Add a default constructor to your ViewModel, and instantiate the property there. Then your controller code should work fine.
0
 
maqskywalkerAuthor Commented:
Great solution. It worked great.
0
 
käµfm³d 👽Commented:
Kaufmed's post is not correct...
I beg to differ. The gist of my post--which you even reiterated--was that the properties were not being instantiated. Whether that instantiation comes from a default constructor or the database, the property still has to be instantiated. Where the data comes from is an implementation detail.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.