- 追加された行はこの色です。
- 削除された行はこの色です。
[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]
-[[戻る>ASP.NET MVC]]
* 目次 [#xe5726ff]
#contents
*概要 [#h6dc5730]
*MVC [#o92da354]
MVCの基本的な考え方
**M(Model)に実装される処理 [#a1340f52]
Modelには、
-B層クラスと、
-B層クラスが返すViewに渡されるEntity, Bean, POCO的なクラス(ViewModel)
がある。
**V(View)に実装される処理 [#ad9a7d3d]
View = 画面表示のための処理。
-マスタページ的なViewと、
-全体View
-部分Viewがある。
**C(Controller)に実装される処理 [#h99848ae]
-Action Methodを実装する。
-Action Methodは、
++「M(Model)」を呼び出して
++「(Bean≒M)」を取得して
++「V(View)」呼び出す。
**モジュールの作成順 [#g4c4867d]
+C(Controller)を作成
+V(View)を作成
+M(Model)を作成
+C(Controller)にAction Methodを追加し、C→M→Vと繋げる。
*C(Controller)関連 [#g454069b]
**URL ルーティング [#abe121d3]
-あらかじめ定義されたルート定義 (URLのパターン) に従い、~
URLからControllerやAction Methodに処理を振り分けること。
-ユーザーがブラウザーに URL を入力すると、~
定義されているルーティング規則を使用してURL が解析され、~
Controllerのパスが特定される。
-例えば、ASP.NET MVCでは、RouteConfig.cs / .vb ファイルにデフォルトで~
以下のようにルーティングが定義されている。~
(このルート定義は、自由にカスタマイズ可能)
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
この時、ブラウザから
http://server/applicationname/Products/Index/1
というURLでリクエストを送信した場合、
http://(Server FQDN名)/(Controller名)/(Action Method名)/(id 値)
ルート定義に従い、ページハンドラは
-Controller名:Products
-Action Method名:Index
-id (Action Methodに渡す値):1
と判断し、
Products Controllerの Index Action Methodを呼び出し、Action Methodの引数として "1" を渡す。~
Action Method名と id 値は省略可能で、Action Method名を省略すると、Index Action Methodが実行される。
-ASP.NET MVC アプリケーションのコントローラーとアクション メソッド~
https://msdn.microsoft.com/ja-jp/library/dd410269.aspx
**Action Method [#w8313d08]
***リクエストデータと引数の関連付け [#i5d9821b]
マップの方法
-パラメタ名と一致した引数を定義~
POST や GET のパラメタの名前と一致した引数を定義しておけば、自動的にマップされる。
--Get ならクエリ文字列のキー名
--Post ならフォームデータのキー名
-FormCollection を使う (Post の場合のみ)~
<form> の中身がコレクション型として保持されたもの。
-Modelクラスを使う (Post の場合のみ)~
ControllerとViewで、Modelクラスのデータを双方向バインディングしている場合に使用される。~
(双方向バインディングについては、[[HTMLヘルパー>#r27d7319]]を参照。)
***戻り値 [#pcb22e7a]
Action Methodの結果として、Action Resultを返す。~
詳細は[[Action Result>#q3d2aae4]]を参照。
**非同期Controller [#lc319892]
-ASP.NET MVC での非同期コントローラーの使用~
https://msdn.microsoft.com/ja-jp/library/ee728598.aspx
--非同期Controllerを使用すると、[[async/await]]を使用し、~
Webサーバのスレッド枯渇を防ぐことができる。
--実行に時間のかかる CPU バインド以外の要求に非同期Controllerを使用すると、~
Webサーバの待機スレッドを他に転用可能になるので、Webサーバのスレッド数を節約し、~
スレッド枯渇による「HTTP 503 (サーバーがビジー状態です。)」を防止できる。
--図から、リクエスト処理開始時とレスポンス処理終了時のスレッドが変わることが解る。~
後のスレッドは独立したスレッドプールから取得する。複雑なのでオーバーヘッドがある。
***旧(AsyncControllerを継承する。) [#hab6cbd4]
-AsyncController を継承する。
-以下の命名規約を守ったAction Methodを定義する。
--ActionNameAsync
--ActionNameCompleted(delegate)
***Task<ActionResult>を返す。 [#m0e7c5c6]
MVC 4 以降であれば、以下のように書ける。
-Action Method内部でTaskを使用する場合、
public Task<ActionResult> Index()
-Action Method内部でasync/await キーワードを使う場合、
public async Task<ActionResult> Index()
***参考 [#c1c3ca5f]
-非同期コントローラを使ってみた - しばやん雑記~
http://blog.shibayan.jp/entry/20100715/1279204349
-ASP.NET MVC 4 の新機能、タスク対応の非同期コントローラを使う - しばやん雑記~
http://blog.shibayan.jp/entry/20111105/1320495813
**Action Result [#q3d2aae4]
Controller のAction Methodは、View の選択と指示として、~
[[ActionResult>https://msdn.microsoft.com/ja-jp/library/system.web.mvc.actionresult.aspx]] クラスのオブジェクトを返す必要がある。
Action Methodで、
return View();
と、Viewを指定しないoverloadで呼び出すと、
/Views/コントローラ名/アクション名.cshtml
を呼び出す。
***ActionResultの種類とヘルパー・メソッド [#o5927f4e]
ActionResult クラスには、以下の種類が存在する。
|種類|概要・用途|コード例(ヘルパー・メソッド)|h
|ViewResult|指定された全体 View の表示を指示する。&br();基本的には [[HTML.BeginForm>#y7008c56]] の場合に使用する。|return View("Result");&br();("Result" は全体 View 名)|
|PartialViewResult|指定された部分 View の表示を指示する。&br();基本的には [[Ajax.BeginForm>#b0eaca55]] の場合に使用する。|return PartialView("Result");&br();("Result" は部分 View 名)|
|RedirectResult|指定した URL にリダイレクトする場合に使用する。|return Redirect("http://www.wings.msn.to/");|
|RedirectToActionResult|指定した Controller, Action にリダイレクトする場合に使用する。|return RedirectToAction("Index");|
|~|指定したルート名にリダイレクトする場合に使用する。|return RedirectToRoute("View Product", new { ProductName = <商品名> });|
|FilePathResult|指定されたパスの内容をファイルとして出力|return File("C:\temp\file.zip", "application/zip", "file.zip");|
|FileContentResult|byte配列の内容をファイルとして出力|return File(bytes, "application/pdf");|
|FileStreamResult|ストリームの内容をファイルとして出力|return new FileStreamResult(fileStream, "application/pdf");|
|ContentResult|プレーン・テキストを出力(Ajax通信)|Return Content("こんにちは、世界!", "text/plain");|
|JsonResult|指定されたコンテンツをJSONとして出力(Ajax通信)|return Json(JsonConvert.SerializeObject(result), JsonRequestBehavior.AllowGet);|
|JavaScriptResult|指定されたコンテンツをJavaScriptスクリプトとして出力|return JavaScript(code);|
|HttpUnauthorizedResult|承認の失敗時にHTTP応答コード「401 Unauthorized」をセット|-|
|EmptyResult|何もしない|-|
-c# - RedirectToAction and RedirectToRoute - Stack Overflow~
http://stackoverflow.com/questions/8944355/redirecttoaction-and-redirecttoroute
-参考
--ActionResult クラス~
https://msdn.microsoft.com/ja-jp/library/system.web.mvc.actionresult.aspx
--ASP.NET MVC ActionResultの派生型 | 宇宙仮面の研究室~
https://uchukamen.wordpress.com/2011/02/06/asp-net-mvc-actionresult%E3%81%AE%E6%B4%BE%E7%94%9F%E5%9E%8B/
--連載:ASP.NET MVC入門:第3回~
ActionResultオブジェクトでアクション操作も自由自在 - @IT~
--- (1/5)~
http://www.atmarkit.co.jp/ait/articles/0907/10/news109.html
--- ~ (5/5)~
http://www.atmarkit.co.jp/ait/articles/0907/10/news109_5.html
***HttpStatusCodeResult [#e8677bb1]
Viewではなく、HTTP状態コードを返す。
-System.Web.Mvc.HttpStatusCodeResult~
https://msdn.microsoft.com/ja-jp/library/system.web.mvc.httpstatuscoderesult.aspx
--System.Web.Mvc.HttpNotFoundResult
--System.Web.Mvc.HttpUnauthorizedResult
*V(View)関連 [#h3fb6308]
View には、
-画面全体を表す「[[全体 View>#a6a0c6e0]]」と、
-画面の一部分のみを表す「[[部分 View>#t0b33738]]」がある。
**ビューエンジン [#z40de977]
Webページのビューエンジンには以下の2つのものがある。
***ASPX [#u5044497]
従来の ASP.NET と同様、~
式やコードブロックを コード・ナゲット(<% ~ %>)で囲む記述形式。~
View の拡張子も、従来の ASP.NET と同様、「*.aspx」で表される。
***Razor(主流) [#id4ef38b]
ASP.NET MVC 3 で登場したビューエンジン。~
式やコードブロックの先頭に「@」を付与する記述形式で、~
冗長なコード・ナゲット(<% ~ %>)が不要になる。~
View の拡張子は、C# の場合は「*.cshtml」、VB の場合は「*.vbhtml」で表される。
***参考 [#kb9c52d6]
-C# Razor構文 基礎文法 総まとめ - @IT~
http://www.atmarkit.co.jp/fdotnet/rapidmaster/rapidmaster_03/rapidmaster_03.html
-第5回 新しいビュー・エンジン「Razor」の基本を理解しよう - @IT~
http://www.atmarkit.co.jp/fdotnet/aspnetmvc3/aspnetmvc3_06/aspnetmvc3_06_01.html
-ASP.NET MVC 3 開発入門 (12) - Razor の文法 - しばやん雑記~
http://blog.shibayan.jp/entry/20110317/1300294985
-ASP.NET MVC のビューは ASPX ではなく Razor を~
http://miso-soup3.hateblo.jp/entry/2013/12/02/030906
**全体 View [#a6a0c6e0]
通常のViewはコレ。
**部分 View [#t0b33738]
部分 View は、「Partial View」ともいわれ、以下の用途で使われる。
--画面の共通化のため~
ASP.NET のユーザーコントロールのように、共通的な画面コンポーネントを部品化しておくもの。
--[[Ajax.BeginForm>#se7ba00c]] の部分更新の範囲を表すため~
[[Ajax.BeginForm>#se7ba00c]] を使用した非同期処理の場合、部分更新の範囲を部分 View で定義する。
***配置場所 [#kccfbcd1]
-/View/Shared/_XXXXPartial.cshtml
-/View/Controller名/_XXXXPartial.cshtml (優先)
***使用方法(部分Viewだけ呼び出す) [#fddc6d15]
-通常
@Html.Partial("_XXXXPartial", model)
-検索機能無し(仮想パス)
@RenderPage("~/View/Controller名/_XXXXPartial.cshtml", model)
-HTML文字列を戻さず、応答ストリームに直接書き出す。~
ViewDataDictionaryの独自のコピーを取得するので、親のViewDataには影響を与えない。
@{ Html.RenderPartial("_XXXXPartial", model); }
-参考
--.net - Html.Partial vs Html.RenderPartial & Html.Action vs Html.RenderAction - Stack Overflow~
http://stackoverflow.com/questions/5248183/html-partial-vs-html-renderpartial-html-action-vs-html-renderaction
***使用方法(Action Methodと部分Viewの両方を呼び出す) [#fd003375]
-子Action Methodの定義
--子Action Methodの定義は、部分Viewが固有データを必要とする場合に追加する。
--通常、全体Viewを呼び出すControllerに、部分Viewの子Action Methodの定義を追加する。
--Action Methodの実行を部分Viewの呼び出し時に限定する場合、[ChildActionOnly]属性を追加する。
--子Action MethodがActionResultを帰す場合、PartialView()ペルパー・メソッドを使用する。
[ChildActionOnly]
public ActionResult Current()
{
・・・
return PartialView("_XXXXPartial", partialViewModel);
}
-子Action Methodの呼び出し
--通常
@Html.Action("XXXX", model)
--HTML文字列を戻さず、応答ストリームに直接書き出す。~
ViewDataDictionaryの独自のコピーを取得するので、親のViewDataには影響を与えない。
@{ Html.RenderAction("XXXX", model); }
**Viewヘルパー [#r27d7319]
従来の ASP.NET では、ASP.NET Web コントロールを使用して、~
ラベルやテキストボックスなどのコントロールを表示していたが、
-ASP.NET MVC では Viewヘルパーを使用する。
***主な Viewヘルパー [#v09eb480]
ASP.NET MVC では、主に以下のような Viewヘルパーが使用できる。
-表示のためのViewヘルパー
|項番|HTMLタグ|Viewヘルパー|h
|1|データの表示|Html.DisplayFor|
|2|入力可能なデータの表示|Html.EditorFor|
|3|ラベルの表示1|Html.DisplayNameFor|
|4|ラベルの表示2|Html.LabelFor|
-HTMLタグに対応したViewヘルパー
|項番|HTMLタグ|Viewヘルパー|h
|1|フォーム <form>|Html.BeginForm または Ajax.BeginForm|
|2|リンク <a>|Html.ActionLink|
|3|テキストボックス <input type="text">|Html.TextBox または Html.TextBoxFor|
|4|テキストエリア <textarea>|Html.TextArea または Html.TextAreaFor|
|5|パスワード <input type="password">|Html.Password または Html.PasswordFor|
|6|チェックボックス <input type="checkbox">|Html.CheckBox または Html.CheckBoxFor|
|7|ドロップダウンリスト <select>|Html.DropDownList または Html.DropDownListFor|
|8|リストボックス <select>|Html.ListBox または Html.ListBoxFor|
|9|ラジオボタン <input type="radio">|Html.RadioButton または Html.RadioButtonFor|
|10|隠しフィールド <input type="hidden">|Html.Hidden または Html.HiddenFor|
-URL生成
|項番|HTMLタグ|Viewヘルパー|h
|1|「~/...」を仮想パスに変換|Url.Content|
|2|Controller、ActionMethod名などから仮想パスを生成|Url.Action|
|3|RouteValueDictionaryから仮想パスを生成|Url.RouteUrl|
-なお、ボタンを生成する Viewヘルパーはないため、~
直接 <input type="button"> または <input type="submit"> を記述する。
***2種類のHTMLヘルパー [#o7472bbe]
Html.xxxx と Html.xxxxFor の2種類のHTMLヘルパーがある。
-Html.xxxx~
''Model から View への一方向バインディング''。~
Html.TextBox("Category") のように、~
プロパティを文字列でマップ指定する場合は、~
"For" がつかない HTMLヘルパーを使用する。
-Html.xxxxFor~
''Model ⇔ View の双方向バインディング''。
--...Forという名称のHTMLヘルパーは、ViewとModelの間での双方向バインディングを行う。
--Html.TextBoxFor(model => model.Category) のように、~
プロパティをラムダ式でマップ指定する場合は、"For" で終わる HTMLヘルパーを使用する。
>ただし、HTTP を経由しての双方向バインディングになるので、~
処理方式的には、以下のような処理シーケンスになる。
--POST 時に、Html.TextBoxFor などへの入力値を、自動的に Model に復元する。
--Controller は、復元された Model から情報を取得して処理を行う。
**マスターページ [#ycd23a70]
ヘッダーやフッター、サイドメニューなどをアプリケーションで共通的に表示させたい場合、~
マスターページを使用してレイアウトを共通化させることができる。~
マスターページには、画面ごとに個別実装が必要な箇所を定義する。
***ビューエンジン [#g5621ed9]
-ビューエンジンが ASPX の場合は、従来の ASP.NET と同様 ContentPlaceHolder を使用する。
-ビューエンジンが Razor の場合は、RenderBody を使用してメインのコンテンツ領域を定義する。
***配置場所と使用方法 [#hed3f79f]
-アプリケーション共通
--配置場所
---/View/Shared/_Layout.cshtml
--使用方法
---/View/Shared/_ViewStart.cshtml のLayoutプロパティ経由で呼び出される。
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
-View単位
--配置場所
---/View/Shared/_XXXXLayout.cshtml
---/View/Controller名/_XXXXLayout.cshtml (優先)
--[[使用方法>#de4835d8]]
***マスターページへのセクションの定義 [#x99b0c9c]
メインのコンテンツ領域以外に、画面ごとに個別実装が必要な箇所を定義する場合、~
RenderSection を使用して「セクション」と呼ばれるサブのコンテンツ領域を定義する。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<!-- メインのコンテンツ領域を描画する場所を定義 -->
@RenderBody()
@Scripts.Render("~/bundles/jquery")
<!-- セクション (サブのコンテンツ領域) を描画する場所を定義 -->
@RenderSection("scripts", required: false)
</body>
</html>
***マスターページの利用 [#j06a55f0]
-例えば、上記のようにマスターページを定義した場合、~
各コンテンツページでは以下のように実装する。
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml"; // 使用するマスターページを指定
}
@* メインのコンテンツ領域 *@
<h2>Index</h2>
@* セクション (サブのコンテンツ領域) *@
@section scripts{
<script type="text/javascript">
...
</script>
}
-上記のように、セクションを実装する場合、
--C# の場合は「@section <セクション名> { ~ }」、
--VB の場合は「@Section <セクション名> ~ End Section」
>で囲む必要がある。
***マスターページのネスト [#de4835d8]
-/View/Controller名/YYYY.cshtml のLayoutプロパティ経由で呼び出される。~
--
@{
Layout = "~/Views/Shared/_XXXXLayout.cshtml";
}
--
@{
Layout = "~/View/Controller名/_YYYYLayout.cshtml";
}
-Viewヘルパー・メソッドの第二引数にLayoutスクリプト名を指定する。
--
return View("YYYY, "_XXXXLayout");
--
return View("YYYY, "_YYYYLayout");
***マスターページの選択 [#u26391c0]
-以下のsectionで選択する場合、~
if文などを使用して、Layoutプロパティに設定する*Layout.cshtmlを切り替える。
@{
Layout = "~/Views/Shared/_XXXXLayout.cshtml";
}
-ActionResultで選択する場合、~
if文などを使用して、return View()の第二引数に設定する部分View名を切り替える。
**BeginForm [#se7ba00c]
BeginFormには以下の2つのものがある。
***Html.BeginFormの特徴 [#w59fdfea]
従来のASPなどでMVC方式を採用した場合と同じ、画面全体を再描画する仕組み。
-リクエスト・レスポンスの度に、画面全体を再描画する。
-ViewState相当の状態保存処理を独自実装する必要がある~
(For付きのViewヘルパー(Html.xxxxFor)を使用する)。
***Ajax.BeginFormの特徴 [#mb6e9e4d]
クライアント・サイドのJavaScriptフレームワークとシームレスに連動して部分更新を実現する仕組み。
-Html.BeginFormとモジュール構造は大きく変わらない。~
ただし、以下のようにHtml.BeginFormと動作は大きく異なる。
--jQueryを使用してリクエストし、
--更新部位のレスポンスを受けてJavaScriptで描画。
-部分更新のターゲットを意識する必要がある。
--送信時に設定したターゲット以外を更新しようとして、結果的に画面遷移する場合、~
RedirectToAction・RedirectToRoute等でActionResultを返すことが出来ないので、~
JavaScriptResult等でJavaScriptを返し、画面遷移をする必要がある。
-参考
--連載:ASP.NET MVC入門:第3回~
ActionResultオブジェクトでアクション操作も自由自在 (4-5) - @IT~
http://www.atmarkit.co.jp/ait/articles/0907/10/news109_4.html
>その性質上、Ajax通信の結果をページの一部に反映させるようなケースで利用することになるだろう。
--ASP.NET MVC で Ajax を使った時の書き方に悩んだ - dunno logs~
http://dany1468.hatenablog.com/entry/2013/01/08/144546
**@model [#c1b6b351]
*M(Model)関連 [#ue2c093c]
**ViewBag, ViewData, TempData [#m41f8886]
ControllerからViewにデータを渡すときに使用する入れ物的なモノ。
-参考
--ViewData vs ViewBag vs TempData - 夜になったら寝る~
http://kyabatalian.hatenablog.com/entry/2015/12/05/232504
***ViewBag [#z43ab48b]
-ViewBag は dynamic object。
***ViewData [#qe522f71]
-ViewData は Dictionary。
***TempData [#i059f7bd]
-TempData は Dictionary。
-TempData は保持されるため、リダイレクト先に値を渡したいときなどに使う。
*検証機能 [#za7f960c]
**Model側 [#qd38a035]
ModelState・・・
-Method
--ModelState.IsValid
--ModelState.AddModelError
**View側 [#za24022f]
-Method
--Html.ValidationSummary~
すべての検証結果のエラー メッセージを要約
--Html.ValidationMessage~
検証結果のエラー メッセージ
--Html.ValidationMessageFor~
検証結果のエラー メッセージ
-CSS
--validation-summary-errors~
ValidationSummaryメソッドによって出力されたメッセージの<div>要素(エラー有)
--validation-summary-valid~
ValidationSummaryメソッドによって出力されたメッセージの<div>要素(エラー無)
--field-validation-error~
ValidationMessageメソッドによって出力されたメッセージの<span>要素(エラー有)
--field-validation-valid~
ValidationMessageメソッドによって出力されたメッセージの<span>要素(エラー無)
--input-validation-error~
検証エラーが発生した要素
**参考 [#j5f7111c]
Action メソッド内で個別にチェックロジックを実装するか、~
Model Meta Dataを使用したチェックが可能。
-お楽しみはこれからだ!
--ASP.NET MVC RCの入力検証~
http://takepara.blogspot.jp/2009/02/aspnet-mvc-rc.html
--強力になったDefaultModelBinder~
http://takepara.blogspot.jp/2009/02/defaultmodelbinder.html
--DataAnnotationsだけでの入力検証の盲点~
http://takepara.blogspot.jp/2009/02/dataannotations.html
-こんなこともできるもよう(Entity Frameworkが必要)。
--ASP.NET MVC 3における検証まわりの改善点 (3-4):CodeZine~
http://codezine.jp/article/detail/6176?p=3
--ASP.NET MVC 4 ことはじめ(5)モデルと足場 - アーキテクチャをスマートに。~
http://d.hatena.ne.jp/architect-wat/20130512/1368360044
----
Tags: [[:ASP.NET MVC]]
Tags: [[:ASP.NET]], [[:ASP.NET MVC]]