【#8】.NET Core MVC初心者チュートリアル Controllerの詳細

スポンサーリンク
初心者目線で解説するチュートリアル (8) プログラミング

ASP.NET Core MVCを初心者目線で解説するチュートリアルの第8回目です。

目次はこちら

今回は以前MVCの概要で解説したControllerをより詳しく解説したいと思います。まずはControllerの本質を考えてみましょう。

Controllerとは

前の記事で述べたように、Controllerの役割はMovelとViewの橋渡しでした。しかし、ModelもViewも使用せず、単純なテキストメッセージを返したり、別のページへのリダイレクトしたり、といった最も基本的な操作であれば単独で行えます。

ASP.NET Core MVCでは、Controllerは他のクラスと全く同じであるため、.csファイル拡張子があり、他の.NETクラスと同じように見えます。しかし、.NET CoreがMVC Controllerとして認識できるようにするには以下を満たす必要があります。

  • プロジェクトの直下の「Controllers」というフォルダに配置する
  • Microsoft.AspNetCore.Mvc.Controllerを継承する(または、 Microsoft.AspNetCore.Mvc.Controllerクラスを継承する独自のクラスから継承する)
  • クラス名は「HomeController」や「ProductsController」などの「Controller」という単語で終わります

これらの規則に従わない場合、Controllerとして扱われません。しかし、Controllerクラスに別の名前(HomeControllerではなくHome)を付ける必要がある場合は、クラス宣言の直前に配置された[Controller]属性を割り当てられます。例を見てみましょう。

Controller属性を付与する

MovieControllerではなく、MovieInfoというControllerを作成しました。例ではControllerクラスを継承していない点に注目してください。コメントアウトされている箇所がController属性です。コメントアウトを解除することで、!https://localhost/MovieInfo/Indexにアクセスできます。もちろん、コメントアウトしないと、Controllerとして認識されないため、アクセスできません。

ただし、できる限り、Microsoft.AspNetCore.Mvc.Controllerクラスを継承する方法をオススメします。なぜなら、MVCで便利な追加機能を利用できるからです。それは、View/Partial View(部分ビュー)を返すメソッドやControllerクラスのHttpContextプロパティのことです。特に、HttpContextプロパティはControllerクラスがクエリ文字列などのHTTP関連情報にアクセスできるようになります。つまり、通常の.NETクラスをWeb対応クラスに変換し、PHPやASP Classicファイル、その他の多くのWebテクノロジに応用できるようになるのです。

Controllerを配置する場所

前述のように、通常、ControllerはMVCプロジェクトのルートにある「Controllers」というフォルダーに直接配置されます。Controller名は用途に基づいて名前が付けられます。(MovieControllerはMovieクラスを扱うといったように) 接尾辞として「Controller」という単語が付けられます。ソリューションエクスプローラーでは、フォルダー構造は次のようになります。

Controllerのフォルダ構造

ここまでで、Controllerとは何か、Controllerがどのように定義されているかをより理解できたと思います。次の章では、Controllerに関連するさまざまなテーマについて詳しく説明します。

ControllerのActionメソッド

Controllerは単なるクラスであるため、フィールド、プロパティ、およびメソッドを持つことができます。特に、ControllerクラスのメソッドはAction(アクション)と呼ばれ、ブラウザとアプリケーションの間の接続の役割を担います。メソッドは、アプリのActionに対応してブラウザ側にデータを返します。

ブラウザはURLを呼び出すことで機能するため、URLに対応するControllerとActionメソッドに変換するものが必要です。たとえば、ユーザーがMovie/1/のようなURLを入力し、 MovieControllerがEditというActionメソッドを使用してこれを処理するようにします。これはルーティングの概念が関わってきます。ルーティングについては、もう少し先で詳しく説明しますが、ひとまずルーティングがURLをController上のActionに接続するものであることを理解しておけばOKです。

Controllerを作成するときは、ControllerクラスのすべてのpublicメソッドがActionと見なされることに注意してください。つまり、理論上、URLを使用してControllerクラスのすべてのメソッドにアクセスできることを意味します。したがって、エンドユーザーが呼び出せないようにするメソッドがコントローラーにある場合は、必ずprivate修飾子を使用してください。もしくは、メソッドをpublicにする必要があるがURLでアクセスさせたくない場合は、[NonAction]属性を使用してください。

Http属性

Actionの呼び出し方法をより細かく制御するために、ActionにHttp属性を付与できます。これにより、.NETはActionのアクセス方法(GETやPOSTなど)について認識します。

GET…データを取得する通信方法
POST…フォームやユーザー入力などのデータを送信する通信方法
[HttpGet]
public IActionResult Edit(int id)
{
    //データを読み取る処理
}
[HttpPost]
public IActionResult Edit(int id, string title, DateTime dt)
{
    //データを書き換える処理
}

例を見てみましょう。Edit Actionはデータを編集するActionです。同じAction名Editが2つあることに注目してください。[HttpGet]のEdit Actionでは引数を元にサーバーからデータを取得し、クライアントへ返します。一方、[HttpPost]のEdit Actionではクライアントで編集された映画タイトルや公開日を引数として受け取り、データを書き換えて保存する処理を行ないます。

同じHttp属性を付与しない限り、同名のメソッドを使用できるのがHttp属性を利用する利点です。

これで、Edit Actionに対してリクエストが行われるたびに、リクエストに応答するActionメソッドは、GET通信かPOST通信かに基づいて決定されます。

状況によっては、複数のHttp属性を指定したい場合があります。たとえば、GET通信とPOST通信の両方でActionにアクセスしたい場合、以下のようにします。

[HttpGet]
[HttpPost]          
public IActionResult Edit()
{
    ...
}

これで、Controllerにおいて最も重要な要素の1つであるActionについて詳しく学びました。Actionは、基本的にActionメソッドやメソッドと呼ばれます。次の章では、ActionResultと呼ばれるActionの結果について説明します。

Action Result

Actionは、要求されたURLがController上のActionと一致したときに呼び出されます(これはルーティングシステムによって実行されます)。ActionメソッドはクライアントにIActionResultインタフェースを実装したデータを返します。(非同期の場合はTask<IActionResult>)

ControllerがMicrosoft.AspNetCore.Mvc.Controllerクラスを継承すると、ActionResultを生成するための様々なメソッドを利用できます。実はすでにこのチュートリアルですでに使用していますが、Viewメソッドがこれにあたります。ViewメソッドはIActionResultインターフェイスを実装するViewResultクラスのインスタンスを生成します。その後、.NETは、そのインスタンスをブラウザへのリクエストへと自動的に変換します。

他にも以下のようなメソッドを利用できます。

  • Content()指定された文字列をテキストとしてクライアントに返します
  • View()…Viewをクライアントに返します
  • PartialView()…部分View(後に詳細解説)をクライアントに返します
  • File()指定されたファイルの内容をクライアントに返します
  • Json()…クライアントにJSON応答を返します
  • Redirect()/RedirectPermanent()…リダイレクト応答をブラウザに返し、ユーザーを別のURLにリダイレクトします
  • StatusCode()…カスタムステータスコードをクライアントに返します

他にもたくさんありますが、自分で実装したり、自分で結果を生成したりすることもできます。ほとんどのメソッドの動作は、プロパティが適切に設定された関連クラスを生成しているだけです。たとえば、Contentメソッドは、ContentResultクラスのインスタンスを生成し、メソッドに渡した値をContentプロパティに入力するだけです。

IActionResultインターフェイスを実装する応答には多くの種類があるため、メソッドのロジックに基づいて、Action Resultを変えるように実装することが多いです。例えば、Edit Actionで要求されたコンテンツが見つかった場合はコンテンツを含むViewを返し、見つからなかった場合は404(ページが見つかりません)エラーを返すことです。次のようになります。

public IActionResult Edit(int id)  
{  
	Movie movie = GetMovie(id);
	if (movie != null)  
		return View(movie);  
	return NotFound();  
}

最初の行では、実装予定のGetMovieメソッドを使用して、要求された製品をロードしようとします。Movieが見つかった場合は、 Viewメソッドを使用してViewに返します。見つからない場合は、基本的にNotFoundResultクラスのインスタンスを作成するNotFoundメソッドを使用して404エラーを返します。つまり、この場合、Actionの結果は2つ考えられますが、私たちは必要に応じて様々なAction Resultを返すことができます。IActionResultインターフェイスを実装するものはすべて自由に返すことができます。

まとめ

ActionController上のメソッドであり、ルーティングのおかげでURLからアクセスできます。ActionはIActionResultインターフェイスに基づいてAction Resultを返すように実装します。また、Action Resultを生成するのに役立つ多くのメソッドがあります。

以上でControllerの詳細についての説明は終わりです。より高度な詳細を含むControllerの解説も以降のチュートリアルで解説しますので、是非最後までお読みくださればと思います。

次の記事は、Viewの詳細に関する内容です。

コメント

タイトルとURLをコピーしました