- 追加された行はこの色です。
- 削除された行はこの色です。
[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]
「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。
-[[戻る>ASP.NET MVC]]
* 目次 [#xe5726ff]
#contents
*概要 [#h6dc5730]
*MVC [#o92da354]
MVCの基本的な考え方
「[[ASP.NET MVCの用語]]」は~
「[[ASP.NET MVCの利用方法]]」と比べて、~
ASP.NET 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に処理を振り分けること。
***ルート定義 [#jd50d3a5]
-ルート定義に従い、URLからControllerやAction Methodに処理を振り分ける。
-ユーザがブラウザに URL を入力すると、 ~
指定したルーティング規則を使用し、URL が解析され、Controllerのパスが特定される。
-ユーザーがブラウザーに URL を入力すると、~
定義されているルーティング規則を使用してURL が解析され、~
Controllerのパスが特定される。
-例えば、ASP.NET MVCでは、RouteConfig.cs / .vb ファイルにデフォルトで~
以下のようにルーティングが定義されている。~
(このルート定義は、自由にカスタマイズ可能)
***既定のルート定義 [#ha8fede4]
-既定のルート定義は、RouteConfig.RegisterRoutesメソッドで定義されている。
-ココでMapRoute()メソッドを使用し、ルートパラメタ(routeName, routeValues)を登録する。
-ルートパラメタ(routeName, routeValues)は、URLの作成にも使用される。
-デフォルトでは以下のようにルート定義されている(自由にカスタマイズ可能)
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
***属性ルーティングによるルート定義 [#b8f1690b]
-個別のルート定義は、RouteConfig.RegisterRoutesメソッドで定義されている。
-ココでMapMvcAttributeRoutes()メソッドを使用し、属性ルーティングを有効化する。
routes.MapMvcAttributeRoutes();
-以下のようにルート定義可能(自由にカスタマイズ可能)
[Route("{controller}/{action}/{id}", Name="xxxx")]
--第一引数には、MapRouteの「URL with parameters」と同じものを指定。
--第二引数のNameはオプションで、[[Htmlヘルパー>#r27d7319]](@Html.RouteLink)で使用できる。
-また、パラメタについて、以下の様な設定を行うことができる。
--オプション設定
--既定値の設定
--制約条件の設定
---データ型指定
---値範囲指定
---正規表現指定
---カスタム制約条件指定
-その他、モデルレベルに既定のActionMethod名を追加可能。
[Route("{action=Top")]
public class XXXXXController : Controller
{
public ActionResult Top() { ・・・ }
}
***ルートプレフィックスの定義 [#n5003deb]
ルートプレフィックスを使用すると、モデルレベルに、~
「URL with parameters」のルート部分の定義を追加できる。
***呼び出されるAction Methodとその引数 [#jff515f7]
この時、ブラウザから
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]
マップの方法
***リクエストデータの取得方法 [#i5d9821b]
-パラメタ名と一致した引数を定義~
-引数とのマップの方法
--[[単方向バインディング>#t62a5795]]~
POST や GET のパラメタの名前と一致した引数を定義しておけば、自動的にマップされる。
--Get ならクエリ文字列のキー名
--Post ならフォームデータのキー名
---Get ならクエリ文字列のキー名
---Post ならフォームデータのキー名
---モデルバインディング~
Modelクラスを使うこともできる(Property名と一致させる)。
-FormCollection を使う (Post の場合のみ)~
--[[双方向バインディング>#i0697eb3]]~
---ControllerのActionMethodとViewの間に、~
ポストバック的な復元動作がある場合に便利。
---Modelクラスを使う(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
**単方向バインディング [#t62a5795]
-クライアントから送信されてきたデータのキー名と、~
ControllerのAction Methodの引数名とが一致するキー値を探して、バインドする。
--非同期Controllerを使用すると、[[async/await]]を使用し、~
Webサーバのスレッド枯渇を防ぐことができる。
-非常に単純な仕組みのため、[[ASP.NET Web Forms]]に比べて、~
単体テストが遣り易くなっている反面、オーバーポスティング攻撃を受け易く、~
セキュリティ的に脆弱とまでは言えないが、課題があると言える。~
--実行に時間のかかる CPU バインド以外の要求に非同期Controllerを使用すると、~
Webサーバの待機スレッドを他に転用可能になるので、Webサーバのスレッド数を節約し、~
スレッド枯渇による「HTTP 503 (サーバーがビジー状態です。)」を防止できる。
-仕組みの詳細は、下記を参照。
--図から、リクエスト処理開始時とレスポンス処理終了時のスレッドが変わることが解る。~
後のスレッドは独立したスレッドプールから取得する。複雑なのでオーバーヘッドがある。
***ValuProvider [#k15b5de0]
Requestを検索してValueを取得するクラス。
***旧(AsyncControllerを継承する。) [#hab6cbd4]
-AsyncController を継承する。
-以下の命名規約を守ったAction Methodを定義する。
--ActionNameAsync
--ActionNameCompleted(delegate)
-既定のValuProvider
|項番|ValuProvider|値取得元|h
|1|ChildActionValueProvider|子アクション|
|2|FormValueProvider|フォーム値|
|3|RouteDataValueProvider|Routeデータ|
|4|QueryStringValueProvider|クエリ文字列|
|5|HttpFileCollectionValueProvider|HTTPファイルのコレクション|
***Task<ActionResult>を返す。 [#m0e7c5c6]
MVC 4 以降であれば、以下のように書ける。
-その他のValuProvider
|項番|ValuProvider|値取得元|h
|1|JsonValueProvider|Json|
|2|CookieValueProvider|Cookie|
|3|SessionValueProvider|Session|
|4|ServerVariablesValueProvider|ServerVariables|
|5|TempDataValueProviderFactory|TempData|
-Action Method内部でTaskを使用する場合、
public Task<ActionResult> Index()
-ValueProviderの処理順~
上記の既定のValuProviderはController.ValueProviderの順番と同じ~
(同じキー名の場合、ValuProviderの順に先勝になる)
-Action Method内部でasync/await キーワードを使う場合、
public async Task<ActionResult> Index()
-ValueProviderの追加~
以下のValueProviderFactoryで順に新規ValueProviderを追加できる。
***参考 [#c1c3ca5f]
-非同期コントローラを使ってみた - しばやん雑記~
http://blog.shibayan.jp/entry/20100715/1279204349
-ASP.NET MVC 4 の新機能、タスク対応の非同期コントローラを使う - しばやん雑記~
http://blog.shibayan.jp/entry/20111105/1320495813
--実装(Global.Application_Startに実装
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
ValueProviderFactories.Factories.Add(new CookieValueProviderFactory());
ValueProviderFactories.Factories.Add(new SessionValueProviderFactory());
ValueProviderFactories.Factories.Add(new ServerVariablesValueProvider());
ValueProviderFactories.Factories.Add(new TempDataValueProviderFactory());
--参考
---ValueProviderFactory クラス (System.Web.Mvc)~
https://msdn.microsoft.com/ja-jp/library/system.web.mvc.valueproviderfactory.aspx
-カスタムValueProviderの自作~
カスタムのValueProviderを実装するために以下のI/Fを使用する。
--IValueProvider(値プロバイダーに必要なメソッドを定義)
--IEnumerableValueProvider(列挙に必要なメソッドを定義)
--IUnvalidatedValueProvider(検証スキップに必要なメソッドを定義)
***ModelBinder [#w5a4ae08]
-ModelBinderは、ValuProviderから必要なデータを取得し、Modelに対して値の設定を行う。
-DefaultModelBinderは、前述の「既定のValuProvider」から必要なデータを検索する。
-カスタムModelBinderの自作も可能。
***ModelBinder属性 [#ne32feb7]
前述のModelBinderの動作を制御する。
通常、
-コレクション系はForm
-プリミティブ型はQueryString
から取得するようになっているが、
以下の属性をAction Methodの引数に対して使用すると、この動作を変更できる。
-FromUri属性~
QueryStringから値を取得するように制御。
-FromBody属性~
Formから値を取得するように制御。
***Bind属性 [#sbe2a0c1]
[[ASP.NET MVC]]は、[[ASP.NET Web Forms]]と比べて、~
オーバーポスティング攻撃を受け易いため引数を明記する仕組み。
-基礎
--Bind属性の引数
---Prefix : Formのname属性のPrefix~
http://stackoverflow.com/questions/1317523/how-to-use-bind-prefix
---Include : Bind対象のProperty名(カンマ区切り)
---Exclude : Bind禁止のProperty名(カンマ区切り)
--設定方法~
[[Action Method>#w8313d08]]に以下の様な属性を付与する。
---[Bind(Include = "PropName1, PropName2...")]
---[Bind(Exclude = "PropName3, PropName4...")]
---[Bind(Include = "PropName1, PropName2...", Exclude = "PropName3, PropName4...")]
-応用(コレクションをBindするときのname or keyの設定方法)~
http://qiita.com/kazuhisam3/items/94542f6d7ccf3acca41c#%E8%A4%87%E5%90%88%E5%9E%8B%E3%81%AE%E9%85%8D%E5%88%97
--配列 or リスト系
---VariableName[n].PropertyName
---[n].PropertyName
--Dictionary系 :
---VariableName[n].Key, VariableName[n].Value.PropertyName
---[n].Key, [n].Value.PropertyName
***参考 [#g93c57b7]
-モデルバインディング
--ASP.NET モデルバインディング - Qiita~
http://qiita.com/kazuhisam3/items/94542f6d7ccf3acca41c
--ASP.NET WEB API モデルバインド その1 値の取得先 - miso_soup3 Blog~
http://miso-soup3.hateblo.jp/entry/20130204/1359976197
--ASP.NET MVC - ASP.NET MVC モデル バインディングの特長と問題点~
https://msdn.microsoft.com/ja-jp/magazine/hh781022.aspx
-DefaultModelBinder
--強力になったDefaultModelBinder~
http://takepara.blogspot.jp/2009/02/defaultmodelbinder.html
-ValueProvider
--ValueProviderを扱うときに気をつけること - miso_soup3 Blog~
http://miso-soup3.hateblo.jp/entry/20120625/1340633706
**双方向バインディング [#i0697eb3]
-ControllerのActionMethodとViewの間に、ポストバック的な復元動作がある場合に便利。
-Modelクラスを使う(Post の場合のみ)。
***[[Modelプロパティ>#c1b6b351]] [#aa9798ee]
@modelで定義したModelプロパティと、
***[[Html.xxxxFor>#o7472bbe]] [#ff74597c]
の[[Htmlヘルパー>#r27d7319]]を使用する。
***双方向バインディングの方法 [#q83170a7]
以下のように双方向バインドする。
-Controller
return View(vm);
-Viewスクリプト
@Model ViewModel
・・・
Html.TextBoxFor?(model => model.Category)
通常、Modelプロパティは、Modelでアクセスするが、
ここでのmodelは[[ラムダ式>ラムダ式って]]の仮引数名なので自由。
***[[XxxxxとXxxxxFor>#o7472bbe]]の違い [#q79b636e]
-[[XxxxxForメソッド>#o7472bbe]]は、モデルバインディングに対応する
--要素名(id, name属性)を自動で設定するため、
--要素名(id, name属性)を指定する引数が無い。
-参考
--Label/TextBox/TextArea/Password/Hidden/ RadioButton/CheckBoxメソッド[Razor] - Build Insider~
http://www.buildinsider.net/web/bookaspmvc5/040207
--TextBoxFor/TextAreaFor/PasswordFor/ HiddenFor/RadioButtonFor/CheckBoxForメソッド[Razor] - Build Insider~
http://www.buildinsider.net/web/bookaspmvc5/040203
**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|何もしない|-|
|項番|種類|概要・用途|コード例(ヘルパー・メソッド)|h
|1|ViewResult|指定された全体 View の表示を指示する。&br();基本的には [[HTML.BeginForm>#w59fdfea]] の場合に使用する。|return View("Result");&br();("Result" は全体 View 名)|
|2|PartialViewResult|指定された部分 View の表示を指示する。&br();基本的には [[Ajax.BeginForm>#mb6e9e4d]] の場合に使用する。|return PartialView("Result");&br();("Result" は部分 View 名)|
|3|RedirectResult|指定した URL にリダイレクトする場合に使用する。|return Redirect("http://www.wings.msn.to/");|
|4|RedirectToActionResult|指定した Controller, Action にリダイレクトする場合に使用する。|return RedirectToAction("Index");|
|5|~|指定したルートパラメタ(routeName, routeValues)にリダイレクトする場合に使用する。|return RedirectToRoute("View Product", new { ProductName = <商品名> });|
|6|FilePathResult|指定されたパスの内容をファイルとして出力|return File("C:\temp\file.zip", "application/zip", "file.zip");|
|7|FileContentResult|byte配列の内容をファイルとして出力|return File(bytes, "application/pdf");|
|8|FileStreamResult|ストリームの内容をファイルとして出力|return new FileStreamResult(fileStream, "application/pdf");|
|9|ContentResult|プレーン・テキストを出力(CSV出力等)|Return Content("こんにちは、世界!", "text/plain");|
|10|JsonResult|指定されたコンテンツをJSONとして出力(Ajax通信)|return Json(JsonConvert.SerializeObject(result), JsonRequestBehavior.AllowGet);|
|11|JavaScriptResult|指定されたコンテンツをJavaScriptスクリプトとして出力|return JavaScript(code);|
|12|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状態コードを返す。
|項番|種類|概要・用途|コード例(ヘルパー・メソッド)|h
|1|HttpStatusCodeResult|任意のHTTP応答コードをセット|-|
|2|HttpUnauthorizedResult|HTTP応答コード「401 Unauthorized」をセット|-|
|3|HttpNotFoundResult|HTTP応答コード「404 NotFound」をセット|-|
-System.Web.Mvc.HttpStatusCodeResult~
https://msdn.microsoft.com/ja-jp/library/system.web.mvc.httpstatuscoderesult.aspx
--System.Web.Mvc.HttpNotFoundResult
--System.Web.Mvc.HttpUnauthorizedResult
***ActionResultの自作 [#kfbc71ec]
可能
**属性 [#radd223d]
***フィルタ属性 [#w535e86f]
-フィルタ属性は、ActionMethodに、以下の様な共通的な処理を追加するために使用する。
--認証処理
--例外処理
--ロギング
--, etc.
-フィルタ属性は、以下に設定可能である。
|項番|適用範囲|設置場所|説明|h
|1|ActionMethod Filter|ActionMethod|ActionMethod単位|
|2|Controller Filter|Controller|Controller単位|
|3|Global Filter|FilterConfig|Application単位|
-以下のフィルタ属性分類があり、実装される処理は項番の順番に呼び出される。
|項番|分類|実装するI/F|実装する処理|h
|1|認証|IAuthenticationFilter|認証に関係する処理|
|2|承認|IAuthorizationFilter|承認(認可)に関係する処理|
|3|Action|IActionFilter|ActionMethodの開始処理の前後処理|
|4|Result|IResultFilter|ActionMethodの終了処理の前後処理|
|5|例外|IExceptionFilter|例外処理|
|6|Override|IOverrideFilter|上位フィルタを上書き|
-標準のフィルタ属性には以下の様なものがある。
|項番|分類|属性|概要|h
|1|承認|Authorize属性|認証済みアクセス(Cookie認証、Token認証)|
|2|承認|[[ChildActionOnly>#fd003375]]属性|子アクションとしてのみ呼び出し可能に設定|
|3|承認|RequireHttps属性|HTTPSアクセスのみ呼び出し可能に設定|
|4|承認|[[ValidateInput]]属性|[[XSS対策に使用する。>https://msdn.microsoft.com/en-us/library/hh882339.aspx]]|
|5|承認|[[ValidateAntiForgeryToken>ASP.NET MVCの利用方法#y1268547]]属性|CSRF対策に使用する。|
|6|例外|HandleError属性|<CustomErrors mode="On or RemoteOnly"/>&br;+FilterConfigに設定した時のカスタムエラーページの定義|
|7|Action/例外/Result|OutputCache属性|出力キャッシュルールの定義|
|8|Action/Result|AsyncTimeout属性|非同期処理のタイムアウトの定義|
|9|Override|OverrideAuthentication属性|グローバル・モデルなど上位で定義されたフィルタを上書き|
|~|~|OverrideAuthorization属性|~|
|~|~|OverrideAction属性|~|
|~|~|OverrideResult属性|~|
|~|~|OverrideException属性|~|
-フィルタ属性は、自作可能。
-参考
--Filters | Microsoft Docs~
https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters
***セレクタ属性 [#y240e1ac]
ControllerからのActionMethodの呼び出しを制御する。
|項番|属性|概要|h
|1|[[HttpXxxxx>ASP.NET MVCの利用方法#qa67aa3b]]属性|Action Methodが受け付けるHTTP Methodを指定|
|2|[[AcceptVerbs>ASP.NET MVCの利用方法#qa67aa3b]]属性|Action Methodが受け付ける1つ以上のHTTP Methodを指定|
|3|NonAction属性|Action Methodでないことを明示する。|
|4|[[ActionName>ASP.NET MVCの利用方法#mbf9d5ab]]属性|Action Method名と別名のAction Nameを付与する。|
セレクタ属性は、自作可能。
**非同期Controller [#lc319892]
***[[C10K問題>C10k problem (C10K問題)]] [#yda40e32]
この技術の登場の背景には [[C10k problem (C10K問題)]]と言うものがある模様。
-ASP.NET MVC での非同期コントローラーの使用~
https://msdn.microsoft.com/ja-jp/library/ee728598.aspx
--非同期Controllerを使用すると、[[async/await]]を使用し、~
Webサーバのスレッド枯渇を防ぐことができる。
--実行に時間のかかる CPU バインド以外の要求に非同期Controllerを使用すると、~
Webサーバの待機スレッドを他に転用可能になるので、Webサーバのスレッド数を節約し、~
スレッド枯渇による「HTTP 503 (サーバーがビジー状態です。)」を防止できる。
--図から、リクエスト処理開始時とレスポンス処理終了時のスレッドが変わることが解る。~
後のスレッドは独立したスレッドプールから取得する。複雑なのでオーバーヘッドがある。
[[内部的には、I/O完了ポートを使用しているものと思われる。>async/await#s4df3070]]
***使い方 [#y811b998]
-旧(AsyncControllerを継承する。)
--AsyncController を継承する。
--以下の命名規約を守ったAction Methodを定義する。
---ActionNameAsync
---ActionNameCompleted(delegate)
-Task<ActionResult>を返す。~
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
*M(Model)関連 [#ue2c093c]
ここでは、B層クラスではなく、
>「B層クラスが返すViewに渡される~
Entity, Bean, POCO的なクラス(ViewModel)」
について説明する。
**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 は保持されるため、リダイレクト先に値を渡したいときなどに使う。
-TempData の詳しい動作は、以下が参考になる。
--ASP.NET MVC TempData は”次のリクエスト”以降も参照できる - miso_soup3 Blog~
http://miso-soup3.hateblo.jp/entry/2013/12/14/070356
**Modelプロパティ [#c1b6b351]
Viewスクリプトから強く型付けされたViewModelを参照する際に使用する。
***使い方 [#ndc87274]
-次の旧構文を使用している場合は、
@inherits System.Web.Mvc.WebViewPage<ViewModelClass>
-次の構文に置き換える。
@model ViewModelClass
-@modelキーワードで指定したViewModelに対しては、Modelプロパティでアクセスする。
--ControllerからViewにModelを渡す。
return View(vm);
--ViewスクリプトでModelを使う。
@Model ViewModel
***参考 [#l9f7b7d2]
-ASP.NET MVC 3: Razorの@model新キーワード:CodeZine(コードジン)~
https://codezine.jp/article/detail/5549
--ScottGu's Blog - ASP.NET MVC 3: New @model keyword in Razor~
https://weblogs.asp.net/scottgu/asp-net-mvc-3-new-model-directive-support-in-razor
*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 で定義する。
--[[Ajax.BeginForm>#mb6e9e4d]] の部分更新の範囲を表すため~
[[Ajax.BeginForm>#mb6e9e4d]] を使用した非同期処理の場合、部分更新の範囲を部分 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);
}
**Viewヘルパー [#r27d7319]
-子Action Methodの呼び出し
--通常
@Html.Action("XXXX", model)
--HTML文字列を戻さず、応答ストリームに直接書き出す。~
ViewDataDictionaryの独自のコピーを取得するので、親のViewDataには影響を与えない。
@{ Html.RenderAction("XXXX", model); }
**Htmlヘルパー [#r27d7319]
(Viewヘルパーという呼称もあるようだが、~
ここではHtmlヘルパーという呼称に統一する)
従来の ASP.NET では、ASP.NET Web コントロールを使用して、~
ラベルやテキストボックスなどのコントロールを表示していたが、
-ASP.NET MVC では Viewヘルパーを使用する。
ASP.NET MVC では、基本的に、以下の様な便利な機能が実装されているHtmlヘルパーを使用する。
-Htmlヘルパーは、サニタイジング処理などを同梱する。
-また、Htmlヘルパーは、[[DataAnnotationの内容を元に表示内容を制御できる。>ASP.NET MVCの利用方法#yb8830b1]]
***主な Viewヘルパー [#v09eb480]
ASP.NET MVC では、主に以下のような Viewヘルパーが使用できる。
***主な Htmlヘルパー [#v09eb480]
ASP.NET MVC では、主に以下のような Htmlヘルパーが使用できる。
-表示のためのViewヘルパー
|項番|HTMLタグ|Viewヘルパー|h
-表示のためのHtmlヘルパー
|項番|HTMLタグ|Htmlヘルパー|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|
-HTMLタグに対応したHtmlヘルパー
|項番|HTMLタグ|Htmlヘルパー|h
|1|フォーム <form>|[[HTML.BeginForm>#w59fdfea]] または [[Ajax.BeginForm>#mb6e9e4d]]|
|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
|項番|HTMLタグ|Htmlヘルパー|h
|1|「~/...」を仮想パスに変換|Url.Content|
|2|Controller、ActionMethod名などから仮想パスを生成|Url.Action|
|3|RouteValueDictionaryから仮想パスを生成|Url.RouteUrl|
-なお、ボタンを生成する Viewヘルパーはないため、~
-なお、ボタンを生成する Htmlヘルパーはないため、~
直接 <input type="button"> または <input type="submit"> を記述する。
***2種類のHTMLヘルパー [#o7472bbe]
Html.xxxx と Html.xxxxFor の2種類のHTMLヘルパーがある。
***Modelバインディング用のHtmlヘルパー [#o7472bbe]
Html.xxxx と Html.xxxxFor の2種類のHtmlヘルパーがある。
-Html.xxxx~
''Model から View への一方向バインディング''。~
''Model から View への[[単方向バインディング>#t62a5795]]''。~
Html.TextBox("Category") のように、~
プロパティを文字列でマップ指定する場合は、~
"For" がつかない HTMLヘルパーを使用する。
"For" がつかない Htmlヘルパーを使用する。
-Html.xxxxFor~
''Model ⇔ View の双方向バインディング''。
''Model ⇔ View の[[双方向バインディング>#i0697eb3]]''。
--...Forという名称のHTMLヘルパーは、ViewとModelの間での双方向バインディングを行う。
--...Forという名称のHtmlヘルパーは、ViewとModelの間での[[双方向バインディング>#i0697eb3]]を行う。
--Html.TextBoxFor(model => model.Category) のように、~
プロパティをラムダ式でマップ指定する場合は、"For" で終わる HTMLヘルパーを使用する。
プロパティをラムダ式でマップ指定する場合は、"For" で終わる Htmlヘルパーを使用する。
>ただし、HTTP を経由しての双方向バインディングになるので、~
>ただし、HTTP を経由しての[[双方向バインディング>#i0697eb3]]になるので、~
処理方式的には、以下のような処理シーケンスになる。
--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スクリプト名を指定する。
-[[Htmlヘルパー>#r27d7319]]・メソッドの第二引数にLayoutスクリプト名を指定する。
--
return View("YYYY, "_XXXXLayout");
--
return View("YYYY, "_YYYYLayout");
***マスターページの選択 [#u26391c0]
-以下のsectionで選択する場合、~
if文などを使用して、Layoutプロパティに設定する*Layout.cshtmlを切り替える。
@{
Layout = "~/Views/Shared/_XXXXLayout.cshtml";
}
-ActionResultで選択する場合、~
--ActionResultで選択する場合、~
if文などを使用して、return View()の第二引数に設定する部分View名を切り替える。
--RouteDataで選択する場合、以下のように実装する。
if ((HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString() == "Account")
&& (HttpContext.Current.Request.RequestContext.RouteData.Values["Action"].ToString() == "Login"))
{
Layout = "~/Views/Shared/_Layout2.cshtml";
}
else
{
Layout = "~/Views/Shared/_Layout.cshtml";
}
-参考
--Layout を変更する4種類の方法(ASP.NET MVC) - Jiro Laboratory~
http://jirolabo.hatenablog.com/entry/2014/12/06/211528
**BeginForm [#se7ba00c]
BeginFormには以下の2つのものがある。
***Html.BeginFormの特徴 [#w59fdfea]
従来のASPなどでMVC方式を採用した場合と同じ、画面全体を再描画する仕組み。
-リクエスト・レスポンスの度に、画面全体を再描画する。
-ViewState相当の状態保存処理を独自実装する必要がある~
(For付きのViewヘルパー(Html.xxxxFor)を使用する)。
-[[ViewState>ASP.NET ViewState]]相当の状態保存処理を独自実装する必要がある~
([[For付きのHtmlヘルパー(Html.xxxxFor)>#o7472bbe]]を使用する)。
***Ajax.BeginFormの特徴 [#mb6e9e4d]
クライアント・サイドのJavaScriptフレームワークとシームレスに連動して部分更新を実現する仕組み。
***[[Ajax.BeginFormの特徴>部分描画とJavaScript#u74ece16]] [#mb6e9e4d]
-Html.BeginFormとモジュール構造は大きく変わらない。~
ただし、以下のようにHtml.BeginFormと動作は大きく異なる。
**@系 [#m101d9c7]
--jQueryを使用してリクエストし、
--更新部位のレスポンスを受けてJavaScriptで描画。
***@inherits [#ja5fd9e8]
[[@model>#e25a6847]]に置き換えられた。
-部分更新のターゲットを意識する必要がある。
--送信時に設定したターゲット以外を更新しようとして、結果的に画面遷移する場合、~
RedirectToAction・RedirectToRoute等でActionResultを返すことが出来ないので、~
JavaScriptResult等でJavaScriptを返し、画面遷移をする必要がある。
***@model [#e25a6847]
[[Viewスクリプトから強く型付けされたViewModelを参照する際に使用する。>#c1b6b351]]
-参考
--連載:ASP.NET MVC入門:第3回~
ActionResultオブジェクトでアクション操作も自由自在 (4-5) - @IT~
http://www.atmarkit.co.jp/ait/articles/0907/10/news109_4.html
>その性質上、Ajax通信の結果をページの一部に反映させるようなケースで利用することになるだろう。
***@section [#mb763834]
[[マスタページを利用する際、定義されたsectionを実装する。>#j06a55f0]]
--ASP.NET MVC で Ajax を使った時の書き方に悩んだ - dunno logs~
http://dany1468.hatenablog.com/entry/2013/01/08/144546
***@helper [#n65f97a7]
Viewスクリプト内に[[Htmlヘルパー>#r27d7319]]を定義。
*M(Model)関連 [#ue2c093c]
**ViewBag, ViewData, TempData [#m41f8886]
ControllerからViewにデータを渡すときに使用する入れ物的なモノ。
***Razor系 [#vbd5ff0e]
-コードナゲット(インライン式)~
式の値の出力
--通常のコードナゲット
@...
--明示的なコードナゲット
@(...)
-参考
--ViewData vs ViewBag vs TempData - 夜になったら寝る~
http://kyabatalian.hatenablog.com/entry/2015/12/05/232504
-コードブロック
--値の代入
--メソッド呼び出し
--オブジェクトの生成
@{...}
***ViewBag [#z43ab48b]
-ViewBag は dynamic object。
-制御構文(ネスト可能)~
if, switch, while, for/foreach
***ViewData [#qe522f71]
-ViewData は Dictionary。
--if
@if(...) {
・・・
}
else if {
・・・
}
else {
・・・
}
***TempData [#i059f7bd]
-TempData は Dictionary。
-TempData は保持されるため、リダイレクト先に値を渡したいときなどに使う。
--switch
@switch (i)
{
case 0:
・・・
break;
case 1:
・・・
break;
・・・
default:
・・・
break;
}
*検証機能 [#za7f960c]
**Model側 [#qd38a035]
ModelState・・・
--while
@while (flg)
{
・・・
}
-Method
--ModelState.IsValid
--ModelState.AddModelError
--for
@for (var i = 0; i < 10; i++)
{
・・・
}
**View側 [#za24022f]
-Method
--Html.ValidationSummary~
すべての検証結果のエラー メッセージを要約
--Html.ValidationMessage~
検証結果のエラー メッセージ
--Html.ValidationMessageFor~
検証結果のエラー メッセージ
--foreach
@foreach (var obj in list)
{
・・・
}
-CSS
--validation-summary-errors~
ValidationSummaryメソッドによって出力されたメッセージの<div>要素(エラー有)
--validation-summary-valid~
ValidationSummaryメソッドによって出力されたメッセージの<div>要素(エラー無)
--field-validation-error~
ValidationMessageメソッドによって出力されたメッセージの<span>要素(エラー有)
--field-validation-valid~
ValidationMessageメソッドによって出力されたメッセージの<span>要素(エラー無)
--input-validation-error~
検証エラーが発生した要素
-静的コンテンツ化
--単一行
@:
--複数行
<text>・・・</text>
**参考 [#j5f7111c]
Action メソッド内で個別にチェックロジックを実装するか、~
Model Meta Dataを使用したチェックが可能。
-コメント
--サーバーコメント
@* ... *@
--HTMLコメント
<!-- ... -->
-お楽しみはこれからだ!
--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
*フォルダ構成 [#c0d7785c]
**既定のフォルダ構成 [#zdede462]
ASP.NET MVC のテンプレートは、グルーピングを目的に、既定で以下のフォルダ構成となっている。~
それぞれのフォルダには、以下のようにファイルを配置することが推奨されている。
-こんなこともできるもよう(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
|項番|フォルダ名|配置されるファイル|備考|h
|1|App_Start|起動時に、初期設定を行うモジュール|-|
|2|Contents|CSS|BundleConfig が使用しているため、既定の CSS ファイルは変更しない|
|3|Controllers|Controller|-|
|4|Models|Model|-|
|5|Scripts|JavaScript|BundleConfig が使用しているため、既定の JavaScript ファイルは変更しない|
|6|Views|View|対応する Controller 名のフォルダ以下に、View のファイルを配置する&br;例&br;Views\(コントローラー名)\Index.cshtml|
**Area (区分)による分割 [#re760150]
Area (区分) とは、ASP.NET MVC アプリケーションを論理的に分割する仕組みのことである。~
(ASP.NET MVC プロジェクトをシステム全体とすると、Area ごとにサブシステム (のようなもの) に分割できる。~
App_Start のマップルートが追加されるような感じ、と理解すると分かりやすいかもしれない)
----
Tags: [[:ASP.NET MVC]]
Tags: [[:.NET開発]], [[:ASP.NET]], [[:ASP.NET MVC]]