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