【T7b】複数のモデルクラスの連携(7/9)
プロジェクトタイプ | (注意: 本文参照) |
---|---|
プロジェクト名 | T7b |
ソリューション名 | PIT7 |
注意
- 本ページの作業内容は 前のページまでの続き になっていることに注意せよ.
- 先に前のページまでをすべて読み,指示されている作業を済ませてから本ページを読むこと.
- プロジェクトの作成作業については準備作業を参照せよ.
7b-7. 「学科」のための Createアクション の変更
このウェブアプリはチュートリアル【T5b】で作成したものを改造したものなので, いまのところT5bと同じ画面遷移を持っている.このアプリの画面遷移を_に再掲する.
データモデルを変更したので,その新規作成や編集,表示のためのビューも変更しなければならない.
まずは_①の新規作成のためのアクション,つまりStudents
コントローラーの
Create
アクションを修正することにしよう.今回は_に示す通り,所属学科を選択するための
ドロップダウンリストを追加する.
ドロップダウンリストに関してはチュートリアル【T5b】でも列挙型の値を選択させるのに使用した.
今回の場合のように「学科」の情報を選択させるドロップダウンリストを作成するためには,当然のことながらデータベースから「学科」の
一覧を取り出してビューに渡す必要がある.このための処理は,Students
コントローラーのCreate
アクション(GET用)で行う.
ドロップダウンリスト( select 要素)の選択肢を設定するためには
SelectListItemクラスの
オブジェクトのコレクションを作って, select 要素に asp-items タグヘルパーを使用してこのコレクションを指定すればよい.
以前の列挙型の例では,HTMLヘルパーのGetEnumSelectList()メソッドが
この指定した列挙型の型情報からSelectListItem
のコレクションを作成してくれていたが,今回はこのコレクションを手動で作成する必要がある.
では Controllers/StudentsController.cs のCreate
アクション(GET用)を_に示す通りに書き換えよう.
ソースコードの冒頭に_に示すusingディレクティブを追記しなければならない点に注意しよう.
|
|
|
|
ここでは2つの技術を使用している. ViewBag
プロパティ と LINQをつかったコレクションの変換 である.
前者に関してはここで初めて紹介する.後者は2年次のプログラミング演習Ⅲ(2023)第10回で詳しく説明しているため,ここでは軽く触れる程度にとどめる.
5行目で使用しているViewBagプロパティは,
以前に説明したViewDataプロパティと同等のもので,アクションからビューに何らかのデータを渡すために使用することができる汎用コンテナである.
今回は作成したSelectListItem
のコレクションをビューに渡すためにViewBag
プロパティを使用している1.
ViewData
と違うのはこのプロパティの型がダイナミックオブジェクトと呼ばれるものである点である.
ダイナミックオブジェクトについての詳しい説明はリンク先に譲るが,このタイプのオブジェクトに対するプロパティの読み書きやメソッド呼び出しといった操作は実行時に解決されるという特徴がある.
もう少し噛み砕いて言えば,このタイプのオブジェクトには 適当なプロパティ名でどんなデータでも格納させることができる .
_の5行目でViewBag.DepartmentList
というプロパティに対する代入を行っているが,これは
ViewData["DepartmentList"]
に代入するのと同等である.このためViewData["
に対して代入したものを,
キー
"]ViewBag.
として取り出すことも,逆にキー
ViewBag.
に対して代入したものを
キー
ViewData["
として取り出すことも可能である.キー
"]
また,7行目では「LINQをつかったコレクションの変換」(参考:プログラミング演習Ⅲ(2023;金澤クラス)第10回)のテクニックを利用している.
ここではLINQの select 句でSelectListItem
クラスのコンストラクタを呼び出すことによって,Department
クラスのコレクションを
SelectListItem
クラスのコレクションに変換している.これまでの例では select 句には範囲変数そのものを渡す使い方しかしていなかったが,このようにして簡便にコレクションの生成を行うことも可能である.
ここで「所属学科」の入力のためのドロップダウンリスト用のデータ生成は,Create
アクション(GET用)以外にも
何カ所かで必要になるので,ヘルパーメソッドとして切り出してそれを呼び出すように変更しよう._に
示すように変更する.
|
|
つぎにこのCreate
アクションのためのビューも変更しよう.Views/Students/Create.cshtmlを_に示すように変更しよう.
|
|
ドロップダウンリストがHTMLの select 要素に対応することは以前にも説明した.30行目の asp-items タグヘルパーに
指定している値を除けば,その直前の「性別」(Sex
)の入力欄のための記述と同じである.「性別」の入力欄と異なり,
「所属学科」の入力欄では asp-items タグヘルパーには,Create
アクション(GET用)においてViewBag
プロパティに渡した
SelectListItem
のリスト(.DepartmentList
)を指定している.
これによりフォームから入力されるデータが増えたので,この送信を処理するためコントローラー側のアクション,
つまりCreate
アクション(POST用)も修正しておこう.
Controllers/StudentsController.cs のCreate()
メソッド([HttpPost]
属性を指定しているほう)を
_に示すように変更しよう.
|
|
ここでの変更は以下の二か所である.
- 4行目
- 引数の
[Bind]
属性の指定にDepartmentId
を追加していること.
- 引数の
- 17行目
- 入力値に誤りがある場合(17~19行目)は
Create
のビューに戻さないといけないため,GET用アクションと同様に学科のリストをViewDag
にセットするために_のSetupDepartmentList()
メソッドを呼び出している.
- 入力値に誤りがある場合(17~19行目)は
以上で_①のCreate
アクションのビューの変更は完了である.
今回は分かりやすさのためにこの方法を用いているが, この方法は推奨されていない 点に注意が必要である.ビューに関連付けられるモデルは1つしかないので,このためにそのページで値を入力させるためのモデルクラスと
SelectListItem
のコレクションを一つに組み込んだしたクラス定義して用いる方が無難ではある(参考: Tag Helpers in forms in ASP.NET Core - Microsoft Docs). ↩︎