はじめに
ASP.NET Core MVC 3.1 のコントローラーついて、自分が学んだことを備忘録として記載します。
このフレームワークに殆ど触れたことが無い方に少しでも参考になれば幸いです。
誤り等あれば、ご指摘頂けますと大変喜びます。
前回の記事
ASP.NET Core MVC 3.1 入門 その2 「MVCプロジェクトの基本構造」
今回の流れ
- MVCパターンの説明
- コントローラーの説明
- コントローラーを作ってみる
- アクションメソッドの説明
- 動かしてみる
- 振り返り
今回のゴール
- MVCパターンにおけるコントローラーの役割を理解する
- コントローラーを追加できる
- アクションメソッドが何かを理解する
環境
- IDE
- Visual Studio 2019
<dt>言語</dt>
<dd>C#</dd>
MVCパターン
コントローラーの説明に入る前に、
まずはMVCパターンについて確認しておきましょう。
全体像を把握したうえで、コントローラーについて具体的にみていきます。
MVCパターンとは
画面表示と、ビジネスロジックの分離を実現するためのアーキテクチャ(設計手法)です。
要はHTMLの生成といった画面表示のための処理と
DBアクセスのようなデータの管理/操作をするための処理
これらを分離させるために先人が考え出したプログラムの作り方の一つです。
MVCというのは構成要素の略称で、以下の単語の先頭文字をそれぞれ取り出したものです。
Model – View – Controller
実現できると、それぞれが分離しているので変更・修正があった場合、お互いに影響を受けづらく、Testability (テスト容易性) が高まるというメリットがあります。
画面に表示する項目の書式変更によってDBアクセス処理に影響が出たり、
DBの軽微な定義変更によって画面表示処理に影響が出るといった事態が発生しづらくなります。
各要素の役割
要素 | 概要 |
---|---|
Model | データの管理/操作といったビジネスロジックを担当 |
View | データ入力用のフォーム、処理結果の表示といったアプリケーションのフロントエンドを担当 |
Controller | ModelとViewの橋渡しを担当 |
コントローラー
コントローラーとは
MVCの全体像を把握したうえで、 コントローラー(Controller)について具体的にみていきます。
MVCにおいて、 Model と View の橋渡しを担当する要素です。
View から受け取った生データを Modelに引き渡し、
Model での処理結果を View に返す
というのが主なお仕事です。
よくある会員登録処理で、 コントローラー のお仕事を確認してみましょう。
- 会員登録フォームに入力された情報を View から受け取る
→ View から生データを受け取る - 実際の会員登録処理(DBアクセス)を担当する Model に情報を引き渡す
→ 受け取ったデータを Model に引き渡す - 会員登録の処理結果(成功/既登録により失敗 etc)を受け取る
→ Model から処理結果を受け取る - ユーザーに会員登録の処理結果を通知するために、 View へ処理結果を返してあげる
→ 受け取った処理結果を View に返す
コントローラーを追加する
では実際にコントローラーを作ってみましょう。
ASP.NET Core MVC 3.1 のプロジェクトを作成する
まずは「Web アプリケーション(モデル ビュー コントローラー)」テンプレートでプロジェクトを作成します。
ソリューションエクスプローラーを眺める
各フォルダ/ファイルの概要については前回の記事をご参照ください。
お作法として、 コントローラー は必ずControllers
フォルダ配下に配置してください。
コントローラー の追加
既にテンプレートに含まれているHomeController
が存在しますが、
新しいコントローラーを追加してみます。
Controllersフォルダを右クリック > 追加 > コントローラー
と進んでください。
スキャフォールディング
以下のようなウィンドウが立ち上がると思います。
「スキャフォールディング」というのは、要は雛形を自動生成する機能のことを示します。
今回はコントローラーの雛形を自動生成してもらうために、この機能を使います。
最初から全ての コントローラーの基底クラスとなるController
クラスを継承してくれたり、読み取りや書き込み用のメソッドを用意してくれたりと、手間が省けるので、 コントローラーを追加する際には普通にクラスとして追加するのではなく、この手順でスキャフォールディング機能を利用することをおすすめします。
今回は「MVC コントローラー - 空」を選択します。
よりリッチな雛形(CRUDに相当するメソッドが用意されている)もありますが、まずはまっさらなコントローラーを使っていきましょう。
続いてファイル名ですが、HelloController
とします。
ここで重要なのは末尾をController
とすることです。
末尾がController
でないと、そのままではコントローラーとして検出されません。
※末尾がController
でない場合は、Controller
属性を付与する必要があります。
クラス名からController
を取り除いた部分がコントローラー名とみなされます。
コントローラークラス
以上でコントローラーは追加できたと思います。
では、追加されたコントローラーのコードを見ていきましょう。
HelloController
まず注目して頂きたいのは、Controller
クラスを継承している点です。
コントローラーは通常Microsoft.AspNetCore.Mvc.Controller
クラスを継承します。
※前身のASP.NET MVC では必須でした。
public class HelloController : Controller
{
public IActionResult Index()
{
return View();
}
}
アクションメソッド
次にIndex
というメソッドをみていきます。
今回は「MVC コントローラー - 空」を使用しましたが、このIndex
メソッドは最初から定義されています。
このメソッドは「アクションメソッド」と呼ばれるものです。
public IActionResult Index()
{
return View();
}
アクションメソッドとは
クライアントからの1リクエスト(ex 登録ボタンの押下)に対して、具体的な処理内容を定義するメソッドです。
上記のIndex
メソッドが正にアクションメソッドとなります。
Controllerクラスとは、関連性を持った複数のアクションメソッドによって構成されます。
逆に言えば、一つ以上のアクションメソッドを束ねたクラスがコントローラーとなります。
アクションメソッドの規約
メソッドをアクションメソッドとして定義するためには、以下に代表される規約を全て守る必要があります。
- コントローラークラス内に定義する
public
-
static
でない - 戻り値が
IActionResult
オブジェクト(後述)
上記のIndex
アクションメソッドは上記の規約を全て守っているので、アクションメソッドということになります。
アクションメソッドの戻り値
繰り返しになりますが、アクションメソッドとはクライアントからの1リクエスト(ex 登録ボタンの押下)に対して、具体的な処理内容を定義するメソッドです。
従って、様々な処理をおこなうことが予想されます。
当然、様々な処理の結果、結果も様々となります。
- 文字列
- ファイルのデータ
- 別のページへの遷移(リダイレクト)
- 要求されたページが存在しない という結果
上記のような様々な結果を表現するために 「IActionResult」を実装した様々なクラス(IActionResult
オブジェクト)が用意されています。
このIActionResult
インターフェースはアクションメソッド内での処理に代わり、実際のHTTPレスポンスを生成する機能を提供しています。
我々が、HTTPレスポンスを直接的に意識することなく、開発ができるのはこの仕組みのおかげというわけです。
代表的なIActionResult
オブジェクトを以下で紹介します。
主なIActionResultオブジェクト
型 | 概要 |
---|---|
ContentResult | テキストデータを返す |
JsonResult | JSON 形式のデータを返す |
ViewResult | テンプレート(ビュー)に基づいてページを返す |
FileContentResult | 指定されたバイト配列をファイルとして返す |
RedirectResult | 指定のアドレスに移動(リダイレクト)する |
RedirectToActionResult | 指定のアクションに移動(リダイレクト)する |
NotFoundResult | ステータスコード 404(NotFound)エラー を返す |
EmptyResult | なにもしない |
利用頻度の高いIActionResult
オブジェクトについては、対応するファクトリメソッドがController
クラスに用意されています。
対応するファクトリメソッドが存在しないものについては、自分でnew
する必要があります。
代表的なものを以下に紹介します。
主なIActionResultオブジェクトのファクトリメソッド
ファクトリメソッド | IActionResultオブジェクト | 備考 |
---|---|---|
Content | ContentResult | |
Json | JsonResult | |
View | ViewResult | デフォルトでは「/Views/コントローラー名/アクション名.cshtml」を読み込む |
File | FileContentResult | |
Redirect | RedirectResult | リダイレクト先をURLで指定する |
RedirectToAction | RedirectToActionResult | リダイレクト先をアクション名(+コントローラー名)で指定する |
NotFound | NotFoundResult | ステータスコードを返却する場合は、StatusCodeResultクラスを利用することもできる(対応するファクトリメソッドがないステータスコードも存在する) |
動作確認
アクションメソッドを修正する
自動生成されたIndex
アクションメソッドを以下のように修正します。
現時点では、Viewを追加していないので、Viewテンプレートを経由せずにテキストデータを返すContentResult
を戻り値として返してみます。
Content
メソッドは、上述した通りContentResult
のファクトリメソッドです。
public class HelloController : Controller
{
public IActionResult Index()
{
return Content("Hello World!"); //修正箇所
}
}
実行
修正したら、F5で実行してみましょう。
テンプレートで用意されているトップページが表示されると思います。
ここでアドレスバーから手入力でURLを変更します。
変更前は以下のようになっているかと思います。
XXXXX
の部分はポート番号を示しています。
環境とタイミング次第で異なりますので、ご自身の画面に表示されているものから変更する必要はありません。
https://localhost:XXXXX/
以下のようにアドレスバーから手入力でURLを変更してください。
末尾にHello/Index
を追加します。
https://localhost:XXXXX/Hello/Index
変更後、Enterを押下すると、以下のように「Hello World!」表示されると思います。
以上で動作確認は終了です。
Hello/Index
とすると、なぜHelloController
のIndex
アクションメソッドが呼び出せるのかについては、次回以降の記事にします。
アクションメソッドを振り返る
ここまでのおさらいも兼ねて、以下のメソッドを言葉にすると
Content
メソッドを呼び出し、テキストデータを返すためのIActionResult
オブジェクト(ContentResult
)を生成し、戻り値として返すIndex
アクションメソッド
ということになります。
public class HelloController : Controller
{
public IActionResult Index()
{
return Content("Hello World!");
}
}