「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>ASP.NET MVC]] * 目次 [#n8bb5f94] #contents *概要 [#qe050a8a] 「[[ASP.NET MVCの利用方法]]」は~ 「[[ASP.NET MVCの用語]]」と比べて、~ 少々高度な応用的トピックをまとめています。 *モジュール化の考え方 [#qfa205f4] **M・V・Cの役割の整理 [#p3416ea2] まず、Model と View と Controller の役割について整理する。 -Model: --アプリケーションの基礎となるデータ構造(ViewModel)、 --およびそのデータを取得・加工する業務ロジック -View:~ Model が保持するデータ(ViewModel)を参照し、ユーザーに表示する。 -Controller: --ユーザーからの入力を受け取り、 --Model に対してデータの取得・加工を指示する。 --その結果を受けて、View に表示を指示する。 **画面 or データモデル、どちらをベースにするか? [#ga2ea366] ASP.NET MVCの開発は、ViewModelのModelMetadata駆動になる。 このため、ViewModelの設計が重要になるが、これを -画面をベースにするか? -データモデルをベースにするか? どちらをベースにするか?でモジュール化が異なってくる。 -前者は、更に以下の2つに分類することができる。 --画面単位のControllerを作成する場合、~ これを「[[全体View ごとに Controller を作成する方式>#va1ffd01]]」と言う。 --機能単位のControllerを作成する場合、~ これを「[[全体View をまとめる 機能単位の Controller を作成する方式>#n9abe57a]]」と言う。 -後者では、データ単位のControllerが作成される。~ これを「[[スキャフォールディング方式>#n9abe57a]]」と言う。~ 「[[スキャフォールディング方式>#n9abe57a]]」は肥大しやすい傾向がある。 **Modelと全体Viewの関係 [#u005fdca] Model (0..1) <---> (1) 全体View ***Model (0) <---> (1) 全体View [#aca38037] 全体View が、Model が保持するデータを何も表示しない状態。(静的なページなど?) ***Model (1) <---> (1) 全体View [#d22aa019] 全体View が、Model が保持するデータを参照し、ユーザーに表示している状態。~ ただし、全体View が参照できるのは「Model のプロパティ」のみであり、~ 全体View から直接 Model のメソッドが呼ぶことはしない。 **Controllerと全体Viewの関係 [#xc23cbb6] 全体View (1..*) <---> (1) Controller ***全体View (1) <---> (1) Controller [#va1ffd01] 1 つの 全体View に対して、1 つの Controller を対応させる考え方。 =「全体View ごとに Controller を作成する方式」 その 全体View からは、対応する Controller へのみリクエストを送る。~ Controller の処理の結果は、対応する 全体View にのみ指示を送る、というもの。~ Controller の処理の結果を、別の 全体View に表示させたい場合は、~ Controller.RedirectToAction メソッドなどを使用して、~ その 全体View に対応した Controller に処理をリダイレクトする。 乱暴な言い方をすれば、従来の ASP.NET の WebForm に近い考え方、と言えるかもしれない。 -画面 (*.aspx) が、全体View に相当する -コードビハインド (*.aspx.cs, *.aspx.vb) が、Controller に相当する -画面を遷移するときは、Response.Redirect メソッドを使用して処理をリダイレクトする -メリット --従来の ASP.NET の経験がある人には、とっつきやすい可能性がある。 -デメリット --Controller クラスの数が膨大になる可能性がある。 ***全体View (1..*) <---> (1) Controller [#n9abe57a] 複数の 全体View に対して、1 つの Controller を対応させる考え方。 アプリケーションの -機能や、 --=「全体View ごとに Controller を作成する方式」 -データ構造に --=「[[スキャフォールディング方式>#z5e00de8]]」 対して、1 つの Controller を対応させる考え方。 -メリット --まとまった業務ごとに Controller を作るので、Controller の数を抑えられる。 -デメリット --複数の 全体View からの処理をすべて 1 つの Controller で受け付けるため、その Controller のコード量が多くなる可能性がある。 ***スキャフォールディング(scaffolding)方式 [#z5e00de8] たとえば、受注処理を行うアプリケーションを考えると、~ 「受注作成画面」・「受注内容更新画面」・「受注削除画面」など、~ 複数の 全体View に分かれていても、同じ「受注」業務=受注エンティティ~ に関するリクエストは 1 つの Controller が受け付ける、という考え方。 -(1 つの Model に対して、その Model に関するリクエストを受け付ける ~ 1 つの Controller、および CRUD を行う 4 つの 全体View が作成される) -スキャフォールディングの場合、M/V/C それぞれの多重度は、以下のようになる。 --全体View (4) <---> (1) Model~ (1 つの Model に対して、CRUD を行う 全体View がそれぞれ作成される) --Controller (1) <---> (1) Model~ (1 つの Model に対して、その Model に関するリクエストを受け付ける Controller が 1 つ作成される) --全体View (4) <---> (1) Controller~ (CRUD を行う 4 つの 全体View は、1 つの Controller にのみリクエストを送る) -しかし、1 つの 全体View で、CRUD 全てを実現できる (CRUD ごとに 全体View が分かれない) 場合は、以下のようになる。~ --全体View (1) <---> (1) Model --Controller (1) <---> (1) Model --全体View (1) <---> (1) Controller **モジュール化の要約 [#j2c8410a] Controllerをどのような単位で作成するかにかかっている。 ***機能やデータ構造に対して 1 つの Controller を対応させる方式 [#td62a820] -全体View (1..*) <---> (1) Model -Controller (1) <---> (1..*) Model -全体View (1..*) <---> (1) Controller ***全体View ごとに Controller を作成する方式 [#se3008cd] -全体View (1..*) <---> (1) Model -Controller (1) <---> (1..*) Model -全体View (1) <---> (1) Controller *Controller の作成 [#ra660e99] **モジュール化 [#t796c394] [[モジュール化の要約>#j2c8410a]]で紹介した、 -[[機能やデータ構造に対して 1 つの Controller を対応させる方式>#td62a820]] -[[全体View ごとに Controller を作成する方式>#se3008cd]] 何れかの方針に合わせて、Controllerを作成する。 **利用可能な属性 [#pb75e024] ***HTTP メソッド属性 [#qa67aa3b] 特定の HTTP メソッドのみを受け入れる属性を付与することができる。 なお、Action MethodにHTTPメソッド属性を指定しなかった場合、~ Action Methodは、すべての HTTP メソッドを受け入れる。 AcceptVerbs 属性は、複数のHTTPメソッドを受け入れるAction Methodの定義に使用する。 -AcceptVerbs 属性は、以下のように利用する。 [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)] public ActionResult XXXXX(・・・) { ・・・ } -以下は、AcceptVerbs 属性で使用できる列挙型の列挙子の一覧~ https://msdn.microsoft.com/ja-jp/library/system.web.mvc.httpverbs.aspx MVC 2 からはHttpGet, HttpPost, HttpPut, HttpDeleteという4つの属性が追加された。 -[HttpGet] メソッド属性 --概要 ---Get メソッドのみ受け入れる。 ---それ以外の HTTP メソッドは受け入れない(404 が返る)。 --ユースケース ---Get で別画面に画面遷移する場合 ---入力項目が無い状態で、同一画面内で状態遷移する場合 -[HttpPost] メソッド属性 --概要 ---Post メソッドのみ受け入れる。 ---それ以外の HTTP メソッドは受け入れない(404 が返る)。 --ユースケース ---フォームの入力項目を Controller に Post する場合。 ---Post で別画面に画面遷移する場合。 -, etc. ***ActionName属性 [#mbf9d5ab] Action Method名と、外部に公開するAction Nameとを別にする。 例えば |項番|Action Method名|ActionName|処理の内容|h |1|Delete|Delete|削除画面の初期表示処理| |2|DeleteConfirmed|Delete|削除処理の実行| ***ValidateAntiForgeryToken属性 [#y1268547] CSRF対策に使用する。~ 複数ブラウザウィンドウ対応がなされているかどうかは未確認。 -View @using (Html.BeginForm()) { @* トークンを埋め込む *@ @Html.AntiForgeryToken() } -Controller // トークンを検証する [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed() { ・・・ } -参考 --連載:ASP.NET MVC入門:第4回~ フィルタ属性による認証/キャッシュ/セキュリティ対策の実装 (5/5) - @IT~ http://www.atmarkit.co.jp/ait/articles/0908/14/news041_5.html --ASP.NET のセキュリティ対策について考える - しばやん雑記~ http://blog.shibayan.jp/entry/20120526/1338001863 --ASP.NET の組み込み機能を活用し、Web 攻撃を回避する~ https://msdn.microsoft.com/ja-jp/library/ms972969.aspx *Model の作成 [#r127e540] **モジュール化 [#eba3e05a] [[モジュール化の考え方>#qfa205f4]]のように、Model には 2 つの意味がある。 -アプリケーションの基礎となるデータ構造 --POCO として作成する。 --XXXXViewModelという名称を付与する。 -そのデータを取得・加工する業務ロジック --通常の業務ロジック・クラスとして作成する。 **利用可能な属性 [#yb8830b1] System.ComponentModel.DataAnnotations属性により、 -検証機能 -[[テンプレート・ヘルパー>#s2b28732]]と呼ばれるHtmlヘルパー -Controllerのスキャフォールディング生成 の動作を制御する事ができる。 -参考 --第3回 モデル・バインドとアノテーション検証の実装 - @IT~ http://www.atmarkit.co.jp/fdotnet/aspnetmvc3/aspnetmvc3_04/aspnetmvc3_04_01.html --第6回 テンプレート機能でビュー開発を効率化 - @IT~ http://www.atmarkit.co.jp/fdotnet/aspnetmvc3/aspnetmvc3_07/aspnetmvc3_07_01.html --ASP.NET MVC の ModelMetadata は奥が深い - しばやん雑記~ http://blog.shibayan.jp/entry/20120108/1326030354 ***DataType属性 [#w26b6337] 型情報を指定することで、 -表示に関する制御属性 -汎用的な[[検証属性>#za53bd3d]] として使用される。 [DataType(DataType.XXXX)] -参考 --DataType 列挙体 (System.ComponentModel.DataAnnotations)~ https://msdn.microsoft.com/ja-jp/library/system.componentmodel.dataannotations.datatype.aspx ---Password列挙子 ---Text列挙子 ---Url列挙子 ---ImageUrl列挙子 ---MultilineText列挙子 ---EmailAddress 列挙子 ---PhoneNumber列挙子 ---PostalCode列挙子 ---Currency列挙子 ---CreditCard列挙子 ---Date列挙子 ---Time列挙子 ---DateTime列挙子 ---Duration列挙子 ---Html列挙子 ---Upload列挙子 ---Custom列挙子 ***DataTypeの派生の属性 [#q63930d1] [[DataType属性>#w26b6337]]と同様に利用される。 -参考 --ASP.NET MVCのモデルでよく使う属性(アノテーション)リスト - Qiita~ http://qiita.com/mrpero/items/607c31895d77815a77cb --DataTypeAttribute クラス (System.ComponentModel.DataAnnotations)~ https://msdn.microsoft.com/ja-jp/library/system.componentmodel.dataannotations.datatypeattribute.aspx ---CreditCard属性 ---EmailAddress属性 ---EnumDataType属性 ---FileExtensions属性 ---Phone属性 ---Url属性 ***DisplayName, Display属性 [#af7225e4] 表示名(Label表示を行なうHtmlヘルパーに使用される) -DisplayName --[DisplayName("xxxx")] -Display --Name ---[Display(Name = "xxxx")] --ResourcesType(国際化対応用) ---[Display(Name = "xxxx", ResourceType = typeof(yyyy))] ***DisplayFormat属性 [#u40f1f5d] フォーマットの指定。 [DisplayFormat(DataFormatXXXX="YYYY")] -DisplayFormatAttribute クラス (System.ComponentModel.DataAnnotations)~ https://msdn.microsoft.com/ja-jp/library/system.componentmodel.dataannotations.displayformatattribute.aspx --DataFormatString(書式指定文字列) --ApplyFormatInEditMode(編集モードで書式を適用するかどうか) --NullDisplayText(null の場合表示するテキスト) --ConvertEmptyStringToNull(空文字列をnullに変換) --, etc. ***UIHint属性 [#kbd81af8] -独自の表示/編集[[テンプレート・ヘルパー>#s2b28732]]を準備する。 -例えばDateTime型を指定したEditorForで~ 使用するjQuery UIのDatepickerを適用する。 ***DisplayColumn属性 [#dda2f14b] -Model間のRelationを設定した際、Modelの表示名に使用しているColumn。 -Model間のRelationは、[[ナビゲーション・プロパティ>#zee4e783]]で設定する。 ***検証属性 [#za53bd3d] 検証属性については、[[コチラ>#f5ad9690]]。 *View の作成 [#m019c385] **モジュール化 [#c1b7f428] **Razer、ASPX の使い分け[#m195fa6e] [[基本、Razer(主流)を使用する。>ASP.NET MVCの用語#z40de977]] **BeginForm の使い分け [#sf5c2980] ASP.NET MVC には、<form> タグを生成する Htmlヘルパーが 2 種類ある。~ BeginForm ヘルパーは引数にコントローラー名、アクション名が付与でき、指定したアクションメソッドにリクエストを送ることができる。 ***HTML.BeginForm [#y7008c56] 通常の <form> タグを生成する場合に使用する。 -全体更新が多数を占める場合 (アクションメソッドの結果として、View 全体を更新する場合)。 -画面リフレッシュにより、リクエスト・レスポンスのステータスを明確にしたい場合。 ***Ajax.BeginForm [#b0eaca55] <form> タグに Ajax リクエスト用の属性が付与され、リクエストが非同期で処理される。 -部分更新が多数を占める場合 (アクションメソッドの結果として、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 View に対して 1 Form? -1 View に対して複数 Form? 複数 Form の場合は Form をネストさせないこと。~ #HTML の仕様で Form のネストは禁止されている。 **Htmlヘルパーの使い分け [#f9430132] ***[[Htmlヘルパー(Html.xxxx と Html.xxxxFor>ASP.NET MVCの用語#o7472bbe]] [#c3297525] -Html.xxxxFor~ --ポスト時にModelデータを復元する場合。 --例えばエラー発生時に、自画面の再表示(≒ポストバック)をする場合。 -Html.xxxx~ 上記以外は、Html.xxxxで良い。 ***GridView的な一覧(グリッド)生成用のHtmlヘルパー [#j629d667] ASP.NET MVC で一覧(グリッド)のある View を作成する場合、以下の 3 種類が考えられる。 -[[WebGrid>ASP.NET MVCのWebGrid]] クラスを使用する~ ソートやページングが容易に実装できる反面、レンダリング部分は多少ブラックボックスになる -<table> タグを自前で生成し、<tr> タグをループで実装する~ ASP.NET の Repeater コントロールのような処理の実装方法(Razorなぶん楽)。 -jqGrid など、OSS の JavaScript ライブラリを使用する。 -[[ASP.NET MVCでDataTableを使用する。]] ***テンプレート・ヘルパー(テンプレートに対応したHtmlヘルパー) [#s2b28732] DisplayForやEditorForなどモデル定義に応じて出力を自在に変えられるHtmlヘルパー。 -Htmlヘルパー --DisplayFor、DisplayForModel:データの表示 ---DisplayFor: ---DisplayForModel:Model単位にテンプレート・ヘルパーを決定する。 --EditFor、EditForModel:データ編集項目の生成 ---EditFor: Htmlヘルパーの第二引数でテンプレート・ヘルパーを指定できる。~ UIHint属性で指定したテンプレート・ヘルパーが使用される。~ 属性の優先度は、UIHint属性 -> DataType属性 -> 実際のデータ型 ---EditForModel:Model単位にテンプレート・ヘルパーを決定する。 -テンプレート・ヘルパー名とテンプレート・ヘルパー配置場所 --DisplayTemplates ---~/View/Shared/DisplayTemplates/DataType名 or Model名.cshtml ---~/View/Controller名/DisplayTemplates/DataType名 or Model名.cshtml --EditorTemplates ---~/View/Shared/EditorTemplates/DataType名 or Model名.cshtml ---~/View/Controller名/EditorTemplates/DataType名 or Model名.cshtml -参考 --[Razor] - Build Insider ---テンプレート関連のビューヘルパー|テンプレートの標準の挙動~ https://www.buildinsider.net/web/bookaspmvc5/040401 ---テンプレートのカスタマイズ|テンプレートを決定する方法~ https://www.buildinsider.net/web/bookaspmvc5/040402 ---モデル単位にテンプレートを決定する - DisplayForModel/EditorForModelメソッド~ https://www.buildinsider.net/web/bookaspmvc5/040404 ***Html.Hidden または Html.HiddenFor [#mcb3c672] タイムスタンプ型など、ユーザに見えない情報だが~ 内部処理に必要な情報を引き継ぐ場合に使用する。 ***カスタムHtmlヘルパー(カスタム・コントロールみたいな) [#uf401f54] -参考 --ASP.NET MVC 5 開発メモ: ASP.NET MVC 5 についての開発メモである。ただしVB.NETがベース > ビューヘルパーを自作する~ http://aspmvc.tokumori-domain.com/view/crt_viewhelper/ --第6回 テンプレート機能でビュー開発を効率化(3/3) - @IT~ http://www.atmarkit.co.jp/fdotnet/aspnetmvc3/aspnetmvc3_07/aspnetmvc3_07_03.html **画面遷移 [#ycae9af6] [[モジュール化の要約>#j2c8410a]]で紹介した、 -[[スキャフォールディング方式>#td62a820]]、 -[[全体View ごとに Controller を作成する方式>#se3008cd]] 共に、画面遷移の処理フローは以下のようになる。 ***処理フロー [#t080759a] +View から、対応する Controller にリクエストを送る +Controller はリクエストを受け付け、Model に処理を指示する +Model は業務ロジックを実行し、データを更新する +Controller は View に表示を指示する ***実装方法 [#v4250bf7] なお、1つの View が、任意の Controller にPOSTリクエストを送る~ [[ASP.NET Web Forms]]の「ページ間ポスティング」的な実装も書けるが、~ View と Controller の関係が複雑になるのでオススメしない。 従って、上記の「4.」で、''どの View に表示の指示をするか''によって、~ 使用する ActionResult クラスを下記のように変える様に実装する。 -その Controller に対応する View に、表示を指示する場合 --ViewResult を使用する -別の Controller に対応する View に、表示を指示する場合 --RedirectToActionResult または RedirectToRouteResult を使用する **モバイル対応 [#h79b3a91] ***Mobil Template [#q17cb912] 「モバイル アプリケーション」テンプレートを使用して、~ モバイルデバイス向けアプリケーションを作成できる。~ このテンプレートでは、jQuery Mobile をベースとしており、~ タッチ操作に最適化した UI を構築できる。 ***DisplayModes [#db369cfe] Bootstrapによるレスポンシブデザインに頼らず、~ PC 向けサイト、モバイル向けサイトの画面を分けるアプローチ。 -DesktopかMobilかは、UserAgentやUserHostAddressを使用して判別している。 -通常、XXXXX.cshtmlとXXXXX.Mobil.cshtmlの2つのViewスクリプトを作成する。~ 上記は、マスタページや部分ViewなどのViewスクリプトにも適用することができる。 --XXXXX.cshtml (PC 向けサイト) --XXXXX.Mobil.cshtml (モバイル向けサイト) -以下のコードを追加してデバイスごとにXXXXX.YYYYY.cshtmlとViewスクリプトを追加する。 --Global.asax の Application_Start メソッドに定義する。 protected void Application_Start() { (中略) DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("iPhone ") { ContextCondition = (context => context.GetOverriddenUserAgent().IndexOf("iPhone ", StringComparison.OrdinalIgnoreCase) >= 0) }); } この時、 -「XXXXX.cshtml」と同じフォルダに -「XXXXX.''iPhone''.cshtml」を作成し、 iPhone 向けのレイアウトを定義すると、 http://server/application/Controller/Index/id という同じ URL に対し、 -PC のブラウザからアクセスした場合、「Index.cshtml」が使用され、 -iPhone からアクセスした場合は「Index.''iPhone''.cshtml」が使用されるようになる。 *情報の持ち回り・状態管理方式 [#i6db0cb0] **ViewState [#l314ae9e] 利用不可能 -必要であれば、ViewState相当の状態保存処理を独自実装する必要がある。 -[[For付きのHtmlヘルパー(Html.xxxxFor)>ASP.NET MVCの用語#o7472bbe]]を使用すれば、~ 双方向バインディングによりポストバックの範囲で値は維持される)。 **Hidden [#a026afb5] 使用可能 **Session [#je17aeb2] 使用可能 *検証機能 [#za7f960c] Action メソッド内で個別にチェックロジックを実装するか、~ ModelMetadataを使用したチェックが可能。 **Model側 [#qd38a035] ***検証属性 [#f5ad9690] 以下の属性を使用して検証可能。 |項番|属性|概要|h |1|[[DataType属性>#w26b6337]](enumDataType, errmsg)|指定のデータ型に変換可能か| |2|Required属性(errmsg)|必須入力| |3|StringLength属性(max, errmsg)|文字列の最大長| |4|MaxLength属性(max, errmsg)|文字列の最大長| |5|MinLength属性(min, errmsg)|文字列の最小長| |6|Range属性(min, max, errmsg)|範囲| |7|RegularExpression属性(pattern, errmsg)|[[正規表現]]| |8|MembershipPassword属性()|パスワード| |9|Compare属性(targetname, errmsg)|比較(e-mailやpasswdの確認用フィールドに使用する)| |10|Remote属性(actionMethod, errmsg)|Ajaxを使用したチェック| |11|CustomValidation属性()|カスタム| 各属性の errmsgプロパティに何も設定しなくても既定でエラーメッセージが出る。 -参考 --ASP.NET MVCのモデルでよく使う属性(アノテーション)リスト - Qiita~ http://qiita.com/mrpero/items/607c31895d77815a77cb --よく使われる入力検証をまとめてみる - しばやん雑記~ http://blog.shibayan.jp/entry/20110708/1310132392 ***[[DataType属性>#w26b6337]] [#mdc47170] [[DataType属性>#w26b6337]]も[[検証属性>#f5ad9690]]として機能する。 -参考 --DataType 属性による検証~ http://surferonwww.info/BlogEngine/post/2016/03/08/validation-by-datatypeattribute-and-default-error-message.aspx ***CustomValidation属性 [#f553a183] ざっくり、以下のようにして、CustomValidation属性を使用する。 -単項目チェック処理~ --プロパティにCustomValidation属性を設定し、呼び出す検証メソッドと関連付ける。 --CustomValidation属性に設定した、staticの検証メソッドを定義する。 --検証メソッドでは、検証結果として、ValidationResultを返す。 -関連チェック処理~ --モデルにCustomValidation属性を設定し、呼び出す検証メソッドと関連付ける。 --CustomValidation属性に設定した、staticの検証メソッドを定義する。 --検証メソッドでは、検証結果として、ValidationResultを返す。 ***自作Validation属性 [#l98ac398] ざっくり、以下のようにして、自作Validation属性を定義して使用する。 -単項目チェック処理~ --プロパティに自作Validation属性を指定して検証パラメタやエラーメッセージを指定する。 -自作Validation属性の作成 --ValidationAttributeクラスを継承した自作Validationを定義する。 --コンストラクタを実装~ 検証パラメタとエラーメッセージを準備(必要に応じてパラメタライズ) --メソッドをoverrideして実装する。 ---FormatErrorMessageメソッドでエラーメッセージを生成 ---IsValidメソッドで検証処理を実装し、検証結果として、boolを返す。 -自作Validation属性をクライアント側検証に対応させる。 --IClientValidationインターフェイスを実装する。 ---属性とViewの橋渡しを行なうGetClientValidationRuleメソッドを実装する。 ---GetClientValidationRuleメソッドでは、IEnumerable<ModelClientValidationRule>を返す。 ---これにより、検証名に対応する検証パラメタとエラーメッセージがHTML側に属性として出力される。 --ModelClientValidationRuleのプロパティ~ https://msdn.microsoft.com/ja-jp/library/system.web.mvc.modelclientvalidationrule_properties.aspx ---ValidationType(検証名) ---ValidationParameters(検証パラメタのKey/Value) ---ErrorMessage(エラーメッセージ) --jQuery Validation プラグインとの関連付け。~ 検証ロジックとを独自jsファイルに定義する。 ---$.Validator.addMethod('検証名'~、 ---$.validator.unobtrusive.adapters.addSingleVal('検証名', '検証パラメタのKey');。 ---BundleConfig.csに、この独自jsファイルをjqueryvalにincludeするバンドル定義を追加する。 ***IValidatableObjectの実装 [#z830ac70] ざっくり、以下のようにして、IValidatableObjectを使用する。~ 複数の検証結果を返せるのは、IValidatableObjectだけである。 -関連チェック処理(IValidatableObject) --モデルでIValidatableObjectを実装してIValidatableObject.Validateメソッドを実装する。 --検証メソッドでは、検証結果として、IEnumerable<ValidationResult>を返す。 **Controller側 [#y0986437] ***検証タイミング [#gea275d0] Action Methodの実行前に、[[モデル・バインディング>ASP.NET MVCの用語#t62a5795]]が行われたタイミング。 ***ModelStateDictionary [#bec6ea56] -概要 --Controller.ModelStateでアクセスできる。 --モデルの状態とモデル・バインディングの検証結果を含む。 -Property --IsValid プロパティ~ モデル・バインディングの検証結果として、モデルの有効・無効を返す。 --Keysプロパティ~ --Valuesプロパティ~ -Method --ModelState.AddModelError()~ エラー情報を追加する。 **View側 [#za24022f] ***サーバ側 [#n811879d] -Method --Html.ValidationSummary~ すべての検証結果のエラー メッセージを要約する。 --Html.ValidationMessage~ 個々の検証結果のエラー メッセージを表示する。 --Html.ValidationMessageFor~ 個々の検証結果のエラー メッセージを表示する。 ***クライアント [#i39f251f] -検証後に適用されるCSSクラス~ これらのCSSクラスをSite.cssファイルに定義しておく。 --validation-summary-errors~ ValidationSummaryメソッドによって出力されたメッセージの<div>要素(エラー有) --validation-summary-valid~ ValidationSummaryメソッドによって出力されたメッセージの<div>要素(エラー無) --field-validation-error~ ValidationMessageメソッドによって出力されたメッセージの<span>要素(エラー有) --field-validation-valid~ ValidationMessageメソッドによって出力されたメッセージの<span>要素(エラー無) --input-validation-error~ 検証エラーが発生した要素 -JavaScript でのクライアント側検証~ --[[jQuery Validation プラグイン>https://jqueryvalidation.org/]]なども使用可能。 --Controller追加で、[[スキャフォールディング>#e701b267]]する際、~ スクリプトライブラリの参照にチェックを入れるとJavaScriptライブラリをインポートできる。 **appSettings [#p175e137] ***クライアント側検証の無効化 [#g8e7a85a] [[CustomValidation属性>#f553a183]]ではクライアント側検証が実行されない。~ 整合性をとるために、クライアント側検証の無効化を行なう。 <add key="ClientValidationEnabled" value="false" /> 若しくは、[[自作Validation属性>#l98ac398]]にクライアント側検証を実装する。 ***控えめなJavaScript [#d50074a3] クライアント側検証に「控えめなJavaScript」のパラダイムが導入されている。 -*.htmlファイル側にJavaScriptではなく、属性を書く。 -JavaScriptは*.jsファイル側に書いて、HTMLとJavaScriptを分離する。 -「控えめなJavaScript」は以下のパラメタで制御できる。 <add key="UnobtrusiveJavaScriptEnabled" value="true"/> -控えめなJavaScript - Wikipedia~ https://ja.wikipedia.org/wiki/%E6%8E%A7%E3%81%88%E3%82%81%E3%81%AAJavaScript **参考 [#j5f7111c] -方法: DataAnnotations 属性を使用してモデル データを検証する~ https://msdn.microsoft.com/ja-jp/library/ee256141.aspx -お楽しみはこれからだ! --ASP.NET MVC RCの入力検証~ http://takepara.blogspot.jp/2009/02/aspnet-mvc-rc.html --DataAnnotationsだけでの入力検証の盲点~ http://takepara.blogspot.jp/2009/02/dataannotations.html -[[Entity Framework>#g04871bf]]と検証処理。 --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 *スキャフォールディング [#e701b267] **概要 [#g794a3ae] スキャフォールディング(Scaffolding)。~ 日本語で「足場」、「骨組み」の意味。 -M(Model)を元に、 --C(Controller) ---CRUDを行うAction Method --V(View) >を自動で生成する機能。 -通常、 --CRUDのAction Methodだけが自動生成される。 --[[Entity Framework>#g04871bf]]によるデータ操作を行う場合、~ Action Methodに加えて View も自動生成できる。 -その他 --[[WebFormでもサポートされている>http://blog.shibayan.jp/entry/20130219/1361281202]]。 **M(Model) [#d93a335a] -使用するModelを選択する。 -Modelの新規作成も可能 ***[[設定する属性>#yb8830b1]] [#p879b91f] ***[[ナビゲーション・プロパティ>Entity Framework#gc07c222]] [#zee4e783] **C(Controller) [#jf4991ce] -M(Model)の複数形 + Controllerという名称になる。 -Action Method --Index --Details --Create --Edit --Delete **V(View) [#te3ce747] -[[Entity Framework>#g04871bf]]を使用すると、以下のようにViewまで自動生成される。 -また、[[Entity Framework>#g04871bf]]を使用しない場合も、個別に、~ ModelMetadataを定義したModelを指定しView追加(スキャフォールディング)ができる。 |項番|View名|対応するAction Method名|使用されるTemplate名|h |1|Index.cshtml|Index|List| |2|Details.cshtml|Details|Details| |3|Create.cshtml|Create|Create| |4|Edit.cshtml|Edit|Edit| |5|Delete.cshtml|Delete|Delete| **テンプレートをオーバーライド [#yb615acb] -ASP.NET MVC - 既定のスキャフォールディング テンプレートをオーバーライドする~ https://msdn.microsoft.com/ja-jp/magazine/dn745864.aspx *ModelMetadataを使用した開発 [#d39da4a0] **[[検証機能>#za7f960c]] [#ya808897] **[[スキャフォールディング>#e701b267]] [#ya2bec28] *脆弱性 [#jd31de6d] **サニタイジング [#m59baf7f] -Htmlヘルパーを使用すると、自動的にサニタイジングが行われる。 -Model のプロパティを直接 View に表示する場合は、自前でのサニタイジングが必要。 **リクエスト検証 [#ra245005] -requestValidationMode を MVC でも利用可能。~ http://stackoverflow.com/questions/6206540/what-does-requestvalidationmode-2-0-actually-do *OAuth / OpenID 対応 [#z14b0107] -この機能は、種々のライブラリによって提供される。 -[[ASP.NET Identity]]を使用すると、~ [[OAuth]]のクライアント & サーバ機能を実装できる。 --[[OAuth]]のクライアント:~ [[ASP.NET Identityの外部ログイン]] --[[OAuth]]のサーバ: [[ASP.NET IdentityのOAuth2によるSTS実装]] *[[Entity Framework]] [#g04871bf] *[[ASP.NET Web API]] [#s5b3bcda] *[[ASP.NET SPA]] [#z1ff5f99] ---- Tags: [[:.NET開発]], [[:ASP.NET]], [[:ASP.NET MVC]]