ASP.NET MVC5にて、Viewに複数のModelを渡す方法がわからずに詰まったのでメモ。
いくつか方法はあるようですが、複数のModelをまとめるViewModelを用意して、それをViewに渡すのがスマートなようです。
環境
- Windows10
- Visual Studio Community 2019
- .NET Framework 4.8
準備
解説のため「WebApplication」というシンプルなMVCプロジェクトを作成しました。
フォルダ構成は以下の通りです。赤枠の部分だけ使用します。
![](https://hirahira.blog/wp-content/uploads/2021/03/2model_to_controller_folder.png)
コードと解説
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を使うようにする。
実行結果
![](https://hirahira.blog/wp-content/uploads/2021/03/2model_to_controller-1024x355.png)
見た目はシンプルですが、2つのリストの中身が表示されました。
参考書籍・サイト
ASP.NET MVC5の貴重な解説書。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fcdn.qiita.com%2Fassets%2Fpublic%2Farticle-ogp-background-9f5428127621718a910c8b63951390ad.png?ixlib=rb-4.0.0&w=1200&mark64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZ3PTkxNiZoPTMzNiZ0eHQ9Q29udHJvbGxlciVFMyU4MSU4QiVFMyU4MiU4OSVFOCVBNCU4NyVFNiU5NSVCMCVFMyU4MSVBRU1vZGVsJUUzJTgyJTkyVmlldyVFMyU4MSVBQiVFNiVCOCVBMSVFMyU4MSU5OSZ0eHQtY29sb3I9JTIzMjEyMTIxJnR4dC1mb250PUhpcmFnaW5vJTIwU2FucyUyMFc2JnR4dC1zaXplPTU2JnR4dC1jbGlwPWVsbGlwc2lzJnR4dC1hbGlnbj1sZWZ0JTJDdG9wJnM9MzBiZWIxMDE0ZDM3ZDA4OThmYjY4MTY0ZDdiMTA3YWM&mark-x=142&mark-y=112&blend64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZ3PTYxNiZ0eHQ9JTQwS2t0a2lZJnR4dC1jb2xvcj0lMjMyMTIxMjEmdHh0LWZvbnQ9SGlyYWdpbm8lMjBTYW5zJTIwVzYmdHh0LXNpemU9MzYmdHh0LWFsaWduPWxlZnQlMkN0b3Amcz04NmYxMGMwZDhlNWYzNzZlYWFhYWMxYmYzZWZmMWUzYQ&blend-x=142&blend-y=491&blend-mode=normal&s=fffe632177b31fc2426728522cc70eb4)
Controllerから複数のModelをViewに渡す - Qiita
#概要Controllerから複数のModelをViewに渡して、表示します。この例では、2つのModel(EmployeeとMachine)を表示します。#出力画面#初期状態からの追加・編…
qiita.com
ASP.NET MVCでビューにおいて複数のデータを渡したい時
www.oborodukiyo.info