前回に引き続きASP.NET Core
を学習メモです。今回はASP.NET Core MVC
の実質的な中心の部分であるコントローラーについて学んでいきます。
前提
1. このコンテンツを扱うこと
- コントローラーの概要
- コントローラーのアクションメソッド
- コントローラーのアクション結果を表す型
- コントローラーのアクションのパラメータマッピング
2. 環境情報
環境/ソフトウェア | 内容 |
---|---|
オペレーティングシステム | Windows 10 1903 |
.NET Core SDK | 2.1.801 |
IDE | Visual Studio Code 1.37.1 |
Browser | Google Chrome 76.0.3809.132 |
3. 前提知識
コントローラの概要
1. コントローラーとは
MVC Webにおいて、コントローラーはリクエスト処理を全体を制御する役割を担っています。
コントローラーは入力データを捕捉し、ビジネス層とデータ層と取りまとめ、リクエストに基づいたレスポンスを返します。
入力データのフォーマットにはQueryString、FormData、HTTP Header、HTTP Bodyなどがあり、
レスポンスにはHTML、 JSON、XML、プレーンテキストなどがあります。
2. コントローラーの定義
すべてのコントローラーは基底クラスはMicrosoft.AspNetCore.Mvc.ControllerBase
を継承しており、ビューエンジンを使うためにはMicrosoft.AspNetCore.Mvc.Controlle
を継承しています。
なので、上記のどちらかクラスを継承すれば、クラスがコントローラーとして扱えます。
3. コントローラーの命名規則
コントローラーはクラス名の後ろにControllerをつけることがMSが推奨するやり方です。
- HomeController
- TestController
Controllerを除いた部分がルーティングに対応し、検出されます。
以下がコントローラーの実装例です。
// MS推奨
public class HomeController : Controller
{
//ControllerName=Home
}
public class HomeController : BaseController
{
//ControllerName=Home
}
public class Test : Controller
{
//ControllerName=Test
}
コントローラーのアクションメソッド
1. アクションメソッドとは
コントローラーのアクションメソッドは、コントローラーがリクエストを受信した後に、処理を行うメソッドです。リクエストURLのActionに対応したアクションメソッド呼び出し、処理結果を返します。
2. アクションメソッドの定義
アクションメソッドの定義例です。必ずパブリックメソッドでなければいけません。
public class HomeController : Controller
{
// /home/index
// or
// /homeのリクエストに対応する
public IActionResult Index()
{
return Content("Hello World - by dongsu.dev");
}
// /home/testのリクエストに対応する
public string Test()
{
return "test";
}
// /home/dosomethingのリクエストに対応する
public void DoSomething()
{
//DoSomething
}
もし、パブリックメソッドを定義したけどリクエストを受け付けさせたくない場合、以下のアノテーションを追加すれば良いです。
public class HomeController : Controller
{
[NonAction]
public void LogicMethod(){
}
}
3. アクションメソッドの戻り値
アクションメソッドが生成する結果はさまざまです。
戻り値はIActionResultインターフェイスを実装する具体的な型がいろいろ定義されており、異なるコンテンツ形式を返せます。ここでMVCで良く扱うアクション結果の型をピックアップしてみました。
型 | 実装方法 | 説明 |
---|---|---|
ViewResult | View() | Razorエンジンが生成したHTMLコンテンツを返します |
PartialViewResult | PartialView() | Razorエンジンが生成した部分ビューのHTMLコンテンツを返します |
ContentResult | Content() | 生のテキストコンテンツを返します |
JsonResult | Json() | 文字通りJSON文字列 |
FileResult | File() | ファイル内容をブラウザーに送信、内容はByte配列 |
RedirectResult | Redirect() | 特定なURLへリダイレクトする |
RedirectToRouteResult | RedirectToAction(), RedirectToRoute() | 特定なコントローラーorアクションメソッドへリダイレクトする |
アクション結果の実装例
まずはControllersフォルダ配下にActionResultTestController.csを作成します。内容は以下です。Controllerを継承することをお忘れなく…
using System;
using Microsoft.AspNetCore.Mvc;
namespace ds.Tutorial.web.Controllers
{
public class ActionResultTestController : Controller
{
}
}
そして、テストしやすいためにStartup.csにルーティング設定をします。
routes.MapRoute (
name: "ActionResultTest",
template: "art/{action}",
defaults : new { controller = "ActionResultTest" }
);
1. ContentResultの実装例
ActionResultTestControllerに以下のアクションメソッドを追加します。
public IActionResult ContentTest () {
return Content ("Content Resutl Test");
}
アプリを起動し、URL{host:port}/art/contenttestをたたくと、Content Resutl Testが表示されるはずです。
2. JsonResultの実装例
同じくアクションメソッドを追加します。
public IActionResult JsonTest () {
return Json (new { Message = "Json Result", Author = "dongsu" });
}
URL{host:port}/art/jsontestへアクセス結果。
{
"message": "Json Result",
"author": "dongsu"
}
3. FileResultの実装例
実装
public IActionResult FileTest () {
var bytes = Encoding.Default.GetBytes ("FileResult Test");
return File (bytes, "application/text", "filetest.txt");
}
URL{host:port}/art/filetestへアクセスするとファイルがダウンロードされ、中身はFileResult Testになります。
3. Redirectの実装例
public IActionResult RedirectTest () {
return Redirect ("https://dongsu.dev");
}
public IActionResult RedirectToActionTest () {
return RedirectToAction ("jsontest");
}
public IActionResult RedirectToRouteTest () {
return RedirectToRoute ("Default", new { Controller = "home", Action = "index" });
}
結果は以下です。
- /art/redirecttestアクセスしたら、https://dongsu.dev へアクセスされる
- /art/redirecttoactiontestアクセスしたら、art/jsontestへアクセスされる
- /art/redirecttoroutetestアクセスしたら、初期画面/へアクセスとなる
パラメータマッピングの実装例
ルートがリクエスト処理を対応するコントローラーに渡した際に、コントローラーはそれに対応するアクションメソッドを見つけ出すと同時に、
HTTPリクエストデータ(QueryString、FormData、HTTP Header、HTTP Bodyなど)に対応するアクションメソッドの引数をマッチングさせます。
対応するリクエストデータと引数がマッチングしない場合、nullがパラメーター値として渡されます。
Controllersフォルダ内でParamsMappingTestcontrollerクラスを作成します。
using System;
using Microsoft.AspNetCore.Mvc;
namespace ds.Tutorial.web.Controllers {
public class ParamsMappingTestcontroller : Controller {
}
}
Startup.csにルーティング設定を追加します。
routes.MapRoute (
name: "ParamsMappingTest",
template: "pmt/{action}/{id?}",
defaults : new { controller = "ParamsMappingTest" }
);
1. 基本パラメータマッピングの実装例
下記のアクションメソッドを追加します。
public IActionResult GetId (int id) {
return Content ($"Action params mapping id : {id}");
}
アプリを起動し、URL{host:port}/pmt/getid/100へアクセスすると以下の結果になります。
Action params mapping id : 100
2. 配列パラメータマッピングの実装例
実装
public IActionResult GetArray (string[] id) {
var message = "Action params mapping";
if (id != null) {
message += string.Join (",", id);
}
return Content (message);
}
URL{host:port}/pmt/getarray/1,2,3,4,5へアクセスすると以下の結果になります。
Action params mapping 1,2,3,4,5
3. クラスパラメータマッチングの実装例
Modelsフォルダを作成し、その中にPersonクラスを実装します。
using System;
namespace ds.Tutorial.web.Models {
public class Person {
public string Name { get; set; }
public int Age { get; set; }
}
}
Controllerにアクションメソッドを追加します。
public IActionResult GetPerson (Person person) {
return Json (new { message = "Action params mapping", data = person });
}
URL{host:port}/pmt/getperson?name=dongsu&age=18へのアクセス結果。
{
"message": "Action params mapping",
"data": {
"name": "dongsu",
"age": 18
}
}
4. クラスパラメータ(リスト型)マッチングの実装例
Controllerにアクションメソッドを追加します。
public IActionResult GetPersonList (List<Person> persons) {
return Json (new { message = "Action params mapping", data = persons });
}
URL{host:port}/pmt/getpersonlist?persons[0].name=dongsu&persons[0].age=18&persons[1].name=mihara&persons[1].age=20へのアクセス結果。
{
"message": "Action params mapping",
"data": [
{
"name": "dongsu",
"age": 18
},
{
"name": "mihara",
"age": 20
}
]
}
5. JSONパラメータマッチングの実装例
Controllerにアクションメソッドを追加します。
public IActionResult GetPersonJson ([FromBody] Person person) {
return Json (new { message = "Action params mapping", data = person });
}
FormBobyなので、ここではHTTPリクエストを送信するツール(Postman, Advenced Rest Clientなど)を用いる必要があります。
備考
今回作成したソースコードです。
では!!( `ー´)ノ