Link to home
Start Free TrialLog in
Avatar of maqskywalker
maqskywalker

asked on

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:

User generated image
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:

User generated image

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:

User generated image
Northwind Employees table looks like this:

User generated image
Adventureworks Department table looks like this:

User generated image

My model for Northwind.edmx looks like this:

User generated image
My model for Adventureworks.edmx looks like this:

User generated image

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.

User generated image
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?
Avatar of kaufmed
kaufmed
Flag of United States of America image

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.
ASKER CERTIFIED SOLUTION
Avatar of Miguel Oz
Miguel Oz
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of maqskywalker
maqskywalker

ASKER

Great solution. It worked great.
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.