[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]] -[[戻る>ASP.NET MVC]] * 目次 [#n8bb5f94] #contents *概要 [#qe050a8a] *モジュール化の考え方 [#qfa205f4] **ModelとViewの関係 [#u005fdca] Model (0..1) <---> (1) View **ControllerとViewの関係 [#xc23cbb6] View (1..*) <---> (1) Controller ***View (1) <---> (1) Controller [#va1ffd01] ASP.NETのWebFormに近い ***View (1..*) <---> (1) Controller [#n9abe57a] [[スキャフォールディング(scaffolding)>ASP.NET MVCの用語#e701b267]]では、この考え方を採用している。 -スキャフォールディングの時のMとCの関係はCRUDと割り切っているから、~ Model (0..1) <---> (1) View (1..*) <---> (1) Controller となる。 -しかし、1画面に、全てのCRUD機能が詰まっていたら、~ Model (0..1) <---> (1) View (1) <---> (1) Controller と[[WebForm>#va1ffd01]]的になる。 ***上記に中立 [#p6842b7c] 1業務、1Controllerなどの考え方でもイイ。 **モジュール化の要約 [#j2c8410a] 以下の2つの方式から選択する。 業務画面は、Modelに対応するCRUD画面を生成するスキャフォールディングと異なり~ Controllerが厳密に1つのModelに紐付かないため、画面単位のモジュール化のほうが適合するかもしれない。 ***スキャフォールディング方式 [#td62a820] Model (0..1) <---> (1) View (1..*) <---> (1) Controller ***ASPXライクな1画面1モジュール方式 [#se3008cd] Model (0..1) <---> View (1) <---> (1) Controller *Controllerの作成 [#ra660e99] **Actionの作成 [#m1334cd3] ***URLルーティング [#zed8012c] ユーザーがブラウザーに URL を入力すると、MVC アプリケーションでは、~ RouteConfig.cs / .vb ファイルに定義されているルーティング規則~ を使用してURL が解析され、コントローラーのパスが特定される。 -コントローラーは、要求を処理する適切なアクション メソッドを決定する。 -既定では、要求の URL は、コントローラー名とアクション名を含むサブパスとして扱われる。 ***HTTP method [#qa67aa3b] -Get : --メソッド定義 : [HttpGet]メソッド属性を付与 ---Get メソッドのみ受け入れる。 ---それ以外の HTTP メソッドは受け入れない(404 が返る)。 --ユースケース: ---Getで別画面に画面遷移する場合 ---入力項目が無い状態で、同一画面内で状態遷移する場合 -Post :~ --メソッド定義 : [HttpPost]メソッド属性を付与 ---Post メソッドのみ受け入れる。 ---それ以外の HTTP メソッドは受け入れない(404 が返る)。 --ユースケース : ---入力項目がある状態でのPostBackする場合。 ---Postで別画面に画面遷移する場合。 -,etc. : ,etc. -メソッド属性を指定しない場合の動作~ 全ての HTTP method を受け入れる。 ***引数 [#i5d9821b] -マップの方法 --POSTやGETのパラメタの名前と一致した引数を定義しておけば、自動的にマップされる。 ---Get ならクエリ文字列のキー名 ---Post ならフォームデータのキー名 --FormCollection を使う (Post の場合のみ)~ <form> の中身がコレクション型として保持されたもの。 --モデルクラスを使う (Post の場合のみ)~ コントローラーとビューで、モデルクラスのデータを双方向バインディングしている場合に使用される。 -HtmlHelperの生成するパラメタ~ HtmlHelperの生成するパラメタのうち、HtmlHelperが使用するものは~ メソッド引数にマップしない(そのパラメタを自分で使いたければ、マップしても構わない)。 ***戻り値 [#v19d2983] [[アクションメソッドの結果として、クライアントに返す適切なビューを選択する。>#q7da2efc]] *Modelの作成 [#r127e540] *Viewの作成 [#m019c385] **Razer、ASPX の使い分け[#m195fa6e] Razer、ASPX構文でModelを使ってHTMLを生成。 ASPX と Razor の記述方法の比較 ||ASPX|Razor|h |インライン式 (プロパティの値を表示する場合など)|<%: Model.Property1 %>|@Model.Property1| |インライン式 (エスケープ処理をスキップし、プロパティの値をそのまま表示する場合)|<%= Model.Property1 %>|@Html.Raw(Model.Property1)| |コードブロック (ロジックを直接 View に記述する場合) (C#)|<% string str = "あいうえお"; %>|@{ string str = "あいうえお"; }| |コードブロック (ロジックを直接 View に記述する場合) (VB)|<% Dim str As String = "あいうえお" %>|@Code&br; Dim str As String = "あいうえお"&br;End Code| **BeginForm の使い分け [#sf5c2980] -HTML(Ajax).BeginFormを記述(そもそもこれはFormタグを生成するヘルパ) --ここで指定した名前のaction属性を持つFormが生成される。 --これがPOSTされると、その名称のコントローラーのActionに入る。 -MicrosoftのASP.NET MVCのAjax.BeginFormは、~ クライアント・サイドのJavaScriptフレームワークとシームレスに連動しているので~ JavaのOSSフレームワークと比べて、かなり実装し易くトラブルも起き難くなっている。 ***HTML.BeginForm [#y7008c56] 部分Viewの作成は共通化のため。 -全体更新が多数を占める場合(画面設計による)。 -レガシー技術で構築したい場合 --クライアント・サイドのJavaScriptフレームワークにより~ ブラックボックス化されておりトラブルシュートに心配がある場合がある。 --ただし、JavaのOSSフレームワークと比べてシームレスに連動しているので~ マイクロソフトのサポートを活用して解決できる可能性が高い。 -画面リフレッシュにより、リクエスト・レスポンスのステータスを明確にしたい場合。 ***Ajax.BeginForm [#b0eaca55] 部分Viewの作成は更新範囲の定義のため。 -部分更新が多数を占める場合(画面設計による)。 -サーバー側処理が非常に重い業務の場合(Ajax は非同期処理のため)。 -画面入力状態を保持したまま POST 送信したい場合 --ViewstateがサポートされないMVCで情報復元処理を割愛したい場合。 -リクエスト・レスポンスのサイズを削減して、性能向上を図りたい場合。 -画面リフレッシュによる、画面のちらつき等をなくしたい場合。 ***参考 [#q5e2db0d] -ajaxの使いどころ~ http://okwave.jp/qa/q8112782.html -Html.BeginForm() vs Ajax.BeginForm() in MVC3 - CodeProject~ http://www.codeproject.com/Articles/429164/Html-BeginForm-vs-Ajax-BeginForm-in-MVC3 **Fromタグの切り方 [#j1aac0c9] -1画面、1Form? -1画面、複数Form? 複数Formの場合はFormをネストさせないこと。~ #HTMLの仕様でFormのネストは禁止されている。 **HTML ヘルパーの使い分け [#c3297525] Html.xxxx と Html.xxxxFor の2種類のHTML ヘルパーがある。 ***Html.xxxx [#o7472bbe] Html.TextBox("Category") のように、プロパティを文字列でマップ指定する場合は、"For" がつかない HTML ヘルパーを使用する。 ***Html.xxxxFor [#b6d55f13] Html.TextBoxFor(model => model.Category) のように、プロパティをラムダ式でマップ指定する場合は、"For" で終わる HTML ヘルパーを使用する。 -...Forを使用してマップ指定すると、ViewとModel間で双方向バインディングされる。 -とは言え、HTTPを経由しての双方向バインディングになるので、~ 処理方式的には、以下の様な処理シーケンスになる。 --POST時に、Formsの情報を自動的にModelに復元する。 --Viewでは復元されたModelから情報を取得して画面を生成する。 ***使い分け [#uc043058] 以下のケースで使い分ける。 -ASPXライクな1画面1モジュール方式か? -スキャフォールディング方式か? -BeginFormの種類 --[[HTML.BeginForm>#y7008c56]]」か? --[[Ajax.BeginForm>#b0eaca55]]」か? 個人的には、 -ASPXライクな1画面1モジュール方式 -[[HTML.BeginForm>#y7008c56]] の場合に最も適合すると考える。 ***グリッドの生成 [#j629d667] WebGridのHTML ヘルパーを使用すると、MVCなのにHTML感を味わえないので、Loopで実装することもある。 **View [#j11c45d9] ***全体View [#od7cef82] -Controller上のActionメソッド(のリージョン)を右クリック、 -Viewを選択するとウィザードが起動する。 -Viewテンプレート(スキャフォールディング)を選択 --Modelへの対応付け~ テンプレートを使用した場合、対応した自動生成がされる。 --オプション ---部分View ---スクリプト・ライブラリ参照 ---レイアウト・ページ(個別設定可能) ***部分View [#j4280e7b] -Viewのフォルダ(Controller名)を右クリック、 -Viewを選択するとウィザードが起動する。 -ウィザードの入力 --_XXXViewと名称を付与する。 --部分Viewにチェック入れる。 -親画面から部分Viewを呼び出す。 --親Viewからは、HTMLヘルパのHtml.Partialを使用する。 --PartialViewNameとModelを引数に取る~ 親と同じModelを渡すか?Model.Modelを渡すか?どちらでもOK。 -Ajax.BeginFormの場合、親画面から部分ViewをDIVで囲っておく。 *画面遷移の考え方 [#q3d2aae4] 「[[ルーティング>ASP.NET MVCの用語#abe121d3]]」で説明したとおり、~ URLでController+Actionを指定すると指定のControllerのActionが実行される。~ #ただし、Actionを省略した時は、Index(既定のAction)が呼ばれる。 **画面遷移のメソッド [#q7da2efc] ***Viewの選択 [#vfdf6f42] 下記ヘルパ・メソッドを使用する。 -Return View("Result") --基本的には「[[HTML.BeginForm>#y7008c56]]」の場合に使用する。 --ControllerからViewResultを選択して返す(通常は自画面を選択)。 --Ajax.BeginFormの場合は、画面の初期表示などにも用いられる -Return PartialView("Result") --基本的には「[[Ajax.BeginForm>#b0eaca55]]」の場合に使用する。 --ControllerからPartialViewResultを選択して返す。 ***画面遷移 [#b9d4724d] -Redirect遷移方式~ --画面に対応するコントローラーを選択する。 --下記のRedirect系ヘルパ・メソッドを使用する。 -Redirect系ヘルパ・メソッド --Return Redirect ---指定されたURLにリダイレクト。 ---Return Redirect("http://www.wings.msn.to/"); --Return RedirectToAction ---アクション名、コントローラー名、ルート値を使用して、指定されたアクションにリダイレクト。 ---Return RedirectToAction("Index") --Return RedirectToRoute ---ルート名とパラメータ値を引数とし、適切なルーティングフレンドリなURLへリダイレクト ---RedirectToRoute("View Product", new { ProductName = <商品名> }); **画面遷移の方法 [#ycae9af6] 以下の方式が考えられる。 ***POSTでView選択 or 画面遷移 [#tc702cd7] -BeginFormに任意のController&Actionを指定する。 -POST遷移後、Actionの中でReturn View("Result") ヘルパ・メソッドを使用して画面遷移する。 ***自ControllerにPOST後にView選択 or 画面遷移 [#qba5f1f4] -BeginFormに自Controller&任意のActionを指定する。 -自ControllerにPOST後、任意のActionの中で --View選択(Transfer的な)~ Return View("Result") ヘルパ・メソッドを使用して画面遷移する。 --画面遷移(Redirect)~ Return RedirectToAction ヘルパ・メソッドを使用して画面遷移する。 ***例外的な遷移 [#nda50fd0] -例外的にクライアントからGETで遷移するケースもある。 -Link, IFRAME, window.open, etc. **URLと画面 [#p47f7c6e] ***View (1..*) <---> (1) Controller(スキャフォールディング)+ POST遷移 [#f5f1cb0f] URLは -Controllerにだけ対応する。 -Viewにまでは対応しない。 ***View (1) <---> (1) Controller(ASPXライク)+ 自ControllerにPOST後に遷移 [#uaea1303] URLは -Controllerに対応する。 -Viewにまで対応する。 *フォルダ構成 [#c0d7785c] **フォルダ分けの意味 [#f6c4f503] -グルーピングのため。 -名前空間が分かれる。 **各フォルダについて [#k32c9ab6] ***App_Start [#s308455d] -初期設定(起動時)を行うモジュールが配置される。 -例えば、RouteConfigはURLの設定を行う。 ***Contents [#x1809e9f] -CSSはココに置く。 -フォルダ構成は自由 -規定のものは変更しない(BundleConfigで使用しているため)。 ***Scripts [#d30cbb78] -Javascriptはココに置く。 -フォルダ構成は自由 -規定のものは変更しない(BundleConfigで使用しているため)。 ***Models [#j9f85022] -Modelはココに置く。 -フォルダ構成は自由 ***Controllers [#i31b0bdb] -Controllerはココに置く。 -フォルダ構成は自由(ただし、フォルダはURLに反映されない) -種類 --EntityFramework~ EntityFrameworkを使用する場合に選択する。 --空~ Action→Index(既定のAction)が生成される。 --スキャフォールディング~ スキャフォールディングに対応したActionが生成される。 -Controllers.Action~ HTTPのGETもPOSTも処理できる(メソッド属性で制限できる)。 ***Views [#w1a844a4] -Viewはココに置く。 -Viewsの下位フォルダは作成できない。 --Controller名に対応するフォルダが自動的に生成される。 --補足:XXXXControllerXXXXという所がController名 -規定のページ --_ViewStart.cshtml ---規定の設定をする、個別に上書き(変更)可能。 ---規定では、Layoutに_Layout.cshtmlを設定している。 --_Layout.cshtml ---規定のマスター・ページ(レイアウト・ページ) ---Sharedの_Layout.cshtml(規定のレイアウト) ***Area [#re760150] なお、Areaを作るとViewsも含めたサブシステム単位のフォルダ分割ができる。~ 以下、App_Startのマップルートが追加されるような感じ。 *情報の持ち回り・状態管理方式 [#i6db0cb0] **Viewstate [#s3a7d336] 利用不可能(必要であれば、自前で実装する必要がある) **Hidden [#o0afdc6f] Formの定義・分割が可能なため、持ち回りも共通化困難。 *チェック処理方式 [#hc015ceb] **クライアント [#i39f251f] JavaScriptでのチェック **サーバ [#k1290bb8] Action内でのチェック **モデルにチェックコードを実装 [#k61bb861] 色々あってよく解らない。 -お楽しみはこれからだ! --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 *脆弱性 [#jd31de6d] **サニタイジング [#m59baf7f] -HTMLヘルパーを使用すれば自動。 -Response.Writeの場合は自前。 **リクエスト検証 [#ra245005] -requestValidationModeをMVCでも利用可能。~ http://stackoverflow.com/questions/6206540/what-does-requestvalidationmode-2-0-actually-do