ASP.NET MVC5にて、Viewに複数のModelを渡す方法がわからずに詰まったのでメモ。
いくつか方法はあるようですが、複数のModelをまとめるViewModelを用意して、それをViewに渡すのがスマートなようです。
環境
- Windows10
- Visual Studio Community 2019
- .NET Framework 4.8
準備
解説のため「WebApplication」というシンプルなMVCプロジェクトを作成しました。
フォルダ構成は以下の通りです。赤枠の部分だけ使用します。
コードと解説
1つ目のサンプルModelです。ID、名前、年齢のプロパティを持ちます。
namespace WebApplication.Models
{
public class MyModel1
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
}
上記2つ目のサンプルModelです。国名と首都名のプロパティを持ちます。
namespace WebApplication.Models
{
public class MyModel2
{
public string Country { get; set; }
public string Capital { get; set; }
}
}
上記2つのModelをプロパティとして持つViewModelを用意します。
using System.Collections.Generic;
namespace WebApplication.Models
{
public class HomeViewModel
{
public List<MyModel1> MyModel1 { get; set; }
public List<MyModel2> MyModel2 { get; set; }
}
}
それぞれのModelのリストにサンプルデータを追加して、homeViewModelのインスタンスを生成し、それをViewに渡します。
using System.Collections.Generic;
using System.Web.Mvc;
using WebApplication.Models;
namespace WebApplication.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
// myModel1のリストを生成してデータを追加
var myModel1List = new List<MyModel1>
{
new MyModel1 { Id = 1, Name = "Mike", Age = 18 },
new MyModel1 { Id = 2, Name = "Jane", Age = 25 },
new MyModel1 { Id = 3, Name = "Bob", Age = 20 }
};
// myModel2のリストを生成してデータを追加
var myModel2List = new List<MyModel2>
{
new MyModel2 { Country = "Japan", Capital = "Tokyo" },
new MyModel2 { Country = "Italy", Capital = "Rome" }
};
// homeViewModelのインスタンスを生成してそれぞれのリストを追加
var homeViewModel = new HomeViewModel
{
MyModel1 = myModel1List,
MyModel2 = myModel2List
};
return View(homeViewModel);
}
}
}
2つのModelのリストが含まれたHomeViewModelがViewに渡されます。
要素はforeach文で取り出すのが一般的ですが、インデックスを指定して1つずつ要素を取り出すこともできます。
@model WebApplication.Models.HomeViewModel
@if (Model != null)
{
@*ループで要素を取り出す*@
<table class="table table-bordered">
<tr>
<th>ID</th>
<th>名前</th>
<th>年齢</th>
</tr>
@foreach (var item in Model.MyModel1)
{
<tr>
<td>@Html.DisplayFor(m => item.Id)</td>
<td>@Html.DisplayFor(m => item.Name)</td>
<td>@Html.DisplayFor(m => item.Age)</td>
</tr>
}
</table>
@*インデックスを指定して要素を取り出す*@
<table class="table table-bordered">
<tr>
<th>国名</th>
<th>首都</th>
</tr>
<tr>
<td>@Html.DisplayFor(m => m.MyModel2[0].Country)</td>
<td>@Html.DisplayFor(m => m.MyModel2[0].Capital)</td>
</tr>
<tr>
<td>@Html.DisplayFor(m => m.MyModel2[1].Country)</td>
<td>@Html.DisplayFor(m => m.MyModel2[1].Capital)</td>
</tr>
</table>
}
(参考)DisplayForビューヘルパーとは
- Modelが持つプロパティのデータ型や付随情報に応じて、適切なタグを生成してくれる便利なテンプレート。
- 例えばModelでデータタイプを「URL」に指定した場合、DisplayForを使うと自動でリンク表示にしてくれる。
- 今回はシンプルなint・string型なので特に効果は感じられないが、基本的にDisplayForを使うようにする。
実行結果
見た目はシンプルですが、2つのリストの中身が表示されました。
参考書籍・サイト
ASP.NET MVC5の貴重な解説書。
Controllerから複数のModelをViewに渡す - Qiita
#概要Controllerから複数のModelをViewに渡して、表示します。この例では、2つのModel(EmployeeとMachine)を表示します。#出力画面#初期状態からの追加・編…
qiita.com
ASP.NET MVCでビューにおいて複数のデータを渡したい時
www.oborodukiyo.info