Controllerから複数のModelをViewに渡す


概要

Controllerから複数のModelをViewに渡して、表示します。
この例では、2つのModel(EmployeeとMachine)を表示します。

出力画面

初期状態からの追加・編集部分

Employee.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;

namespace WebApplication1.Models
{
    public class Employee
    {
        public int Id { get; set; }
        [DisplayName("Name")]
        public string Name { get; set; }
        [DisplayName("Address")]
        public string Address { get; set; }
        [DisplayName("Birthday")]
        public DateTime Birthday { get; set; }
    }
}
Machine.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;

namespace WebApplication1.Models
{
    public class Machine
    {
        public int Id { get; set; }
        [DisplayName("Name")]
        public string Name { get; set; }
        [DisplayName("Manufacturer")]
        public string Manufacturer { get; set; }
        [DisplayName("Beginning of use")]
        public DateTime UseStartDate { get; set; }
    }
}
HomeViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WebApplication1.Models;

namespace WebApplication1.Models
{
    public class HomeViewModel
    {
        public IEnumerable<Employee> Employees { get; set; }
        public IEnumerable<Machine> Machines { get; set; }
    }
}
HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebApplication1.Models;

namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            HomeViewModel myView = new HomeViewModel();
            myView.Employees = GetEmployee();
            myView.Machines = GetMachines();
            return View(myView);
        }
        private List<Employee> GetEmployee()
        {
            List<Employee> employees = new List<Employee>();
            employees.Add(new Employee { Id = 1, Name = "Alex", Address = "NewYork", Birthday = new DateTime(1985, 1, 1) });
            employees.Add(new Employee { Id = 2, Name = "Ben", Address = "London", Birthday = new DateTime(1989, 6, 13) });
            employees.Add(new Employee { Id = 3, Name = "Chris", Address = "Tokyo", Birthday = new DateTime(1993, 11, 14) });
            return employees;
        }
        private List<Machine> GetMachines()
        {
            List<Machine> machines = new List<Machine>();
            machines.Add(new Machine { Id = 1, Name = "My favorite machine", Manufacturer = "Constructor Inc", UseStartDate = new DateTime(1978, 8, 19) });
            return machines;
        }
    }
}
Index.cshtml
@model WebApplication1.Models.HomeViewModel
@{
    ViewBag.Title = "Home Page";
}

<div class="row">
    <div class="col-md-6">
        <table class="table">
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Employees.First().Id)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Employees.First().Name)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Employees.First().Address)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Employees.First().Birthday)
                </th>
            </tr>
            @foreach (var item in Model.Employees)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Id)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Name)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Address)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Birthday)
                    </td>
                </tr>
            }
        </table>
    </div>
    <div class="col-md-6">
        <table class="table">
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Machines.First().Id)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Machines.First().Name)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Machines.First().Manufacturer)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Machines.First().UseStartDate)
                </th>
            </tr>
            @foreach (var item in Model.Machines)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Id)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Name)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Manufacturer)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.UseStartDate)
                    </td>
                </tr>
            }
        </table>
    </div>
</div>

参考

下記の記事で複数のModelをViewに渡す方法が6通り紹介されていました。
Multiple Models in Single View in MVC

その上で、この記事の投稿者は

Which if these would be considered best practice?

という問いかけに対して

My choice is always ViewModel

と回答していたので、この方法を採用しました。