Createアクションメソッド
Createアクションメソッドでは、初回アクセス時に、Create.aspxを呼び出しています。また、入力された項目を基に1レコードを新規作成し、そのデータのModelを更新し、その後テーブルに更新結果を反映させます。
using System.Linq; using System.Web.Mvc; using SampleMvcApplicationCS.Models; namespace SampleMvcApplicationCS.Controllers { public class PubsController : Controller { pubsEntities pubs = new pubsEntities(); <中略> // 【2】作成ボタンクリック時 // POST: /Pubs/Create [AcceptVerbs(HttpVerbs.Post)] public ActionResult Create(titles Titles, FormCollection collection) { // 【2】作成ボタンクリック時(検証) if (Titles.title_id.Trim().Length == 0) ModelState.AddModelError("title_id", "title_idはnullを許容していません。"); // フレームワーク側が既定で検証している部分を修正(英語→日本語へ) if (ModelState["pubdate"].Errors.Count > 0) { ModelState.AddModelError("pubdate", "pubdateの項目は、日付型を入力してください。"); // 0項目目のメッセージ(英語)を削除 ModelState["pubdate"].Errors.RemoveAt(0); } // 検証メッセージが格納されているかチェック(なければTrue) if (ModelState.IsValid) { try { // 【3】作成ボタンクリック時(データの作成) // titlesEntityにレコードを追加する pubs.AddObject("titles", Titles); // 更新を反映させる pubs.SaveChanges(); // Index.aspxページにリダイレクト return RedirectToAction("Index"); } catch { return View(); } } return View(); } <中略> } }
【1】初回アクセス時
既定値があれば、それを出力させる処理を記述しますが、ここでは既定値がないので、Create.aspxの呼び出しのみ行っています。URLルーティング結果は/Pubs/Create/です(図15)。
【2】作成ボタンクリック時(検証)
検証機能の初期設定として、指定された型以外が入力された後で、ポストが行われると型違いであるエラーメッセージ"A value is required."が表示されます(図16)。
このように、型違い部分はフレームワークが行ってくれるので、開発者が検証機能で記述する必要があるのは文字数チェックやnull値の許容になります。
ただしフレームワークが提供するメッセージは英語のため、日本人が利用する場合、抵抗を感じるユーザーの方が多いでしょう。
【2】では、次の検証を行います。
- 主キー(title_id)のみnullを許容しないので、nullの場合検証メッセージを表示
- 英語のメッセージを削除し、日本語で該当エラーメッセージの表示
最初にCreateメソッドの第1パラメタにModel名を追記します。Modelのインスタンス化に失敗した場合は該当項目には初期値が入ります。このサンプルで重要なポイントとして、日付型の初期値には、nullではなく「0001/01/01 00:00」が入ります。そこで、Modelのインスタンス化が失敗しうる入力がpubdateの項目にあった場合、「pubdateの項目は、日付型を入力してください。」と表示します。
主キーのnullチェックはTrimメソッドで空白文字を削除した後、Lengthメソッドで文字数を取得し、0だった場合は入力されていないので、エラーメッセージをModelStateコレクションに追加します。
続いて、英語のメッセージの削除ですが、インスタンス化が失敗した時に、フレームワーク側でModelState.AddModelError("pubdate", "A value is required.");
の処理が実行されたのと同じ状態になっています(実際にはModelErrorオブジェクトがModelStateコレクションのErrorsプロパティに追加されます)。そこで、ModelStateコレクションにキー"pubdate"の中にあるErrorsプロパティに値が格納されているかチェックし、入っていた場合に英語のメッセージがあると判断し、日本語のエラーメッセージをModelStateコレクションに追加後、英語のメッセージを削除します(変換後の表示は図17)。
それぞれの検証が終了後、IsValidメソッドを使い、ModelStateコレクションにエラーメッセージが入っていない場合、データの作成の処理に進み、エラーメッセージが入っていた場合は、エラーメッセージをViewPageに表示します。
【3】作成ボタンクリック時(データの作成)
検証終了後、ModelのUpdateModelメソッドを使い、全ての項目を更新します。その後、AddObjectメソッドを使用してレコードを追加します。第1パラメタはEntity名、第2パラメタは追加するレコードを設定します。続いて、EDMからDBへの更新を反映させるSaveChangesメソッドを使い、DBへのレコード更新も行っています。
最後に、RedirectToActionメソッドにより、Index.aspxページにリダイレクトしています。
以上で設定は全て完了です。実行すると図10~18になります。
実際に組み始めると、わずか十分程でここまでの処理が全て記述できるようになっています。スキャフォールディング機能を実務でそのまま利用することはないかもしれませんが、ASP.NET MVCを触れ始める際にはルーティングの理解とMVCの利用方法を学習する最適の教材になるといえます。
ASP.NET MVCのリクエストフロー
サンプルアプリケーションを作成した後で、ASP.NET MVCのリクエストフローが気になる方もいるかと思うので、簡単にですが、ASP.NET MVCのリクエストフローについても解説します。現時点でASP.NET MVCのソースは公開されていますが、あくまで一部のみの公開で詳細な部分は依然として隠ぺい化されています。公開されている範囲でのASP.NET MVCのアーキテクチャについて簡単に解説します(図19)。
URL Requestがあると、最初にUrlRoutingModuleオブジェクトがリクエストを受け取ります。続いて、HTTP handler(HTTPリクエストを適切な処理に関連付けるASP.NETの基本クラス)を継承したMvcHandlerがリクエストを解析し、ControllerクラスとActionメソッドを特定します。そしてインスタンスを生成し、Actionを呼びます。MVCフレームワークはControllerのsuffix部分をURLルーティングで設定されたControllerカテゴリ部分に加えます。actionカテゴリは呼ばれるメソッド名です。Actionメソッド内ではViewを作成するViewPageを指定して戻り値を渡します。この時、Controllerクラスは指定されたページのインスタンスを生成し、それを呼び出します。通常のASP.NETのリクエストフローとは大きく異なる点をしっかりと理解する必要があります。
まとめ
ASP.NET MVCフレームワークは従来のASP.NET開発とはまったく異なるので、ASP.NETでしか開発をしたことがない方にとっては、ASP.NET AJAXのように気軽に体感できない分、非常にハードルの高いフレームワークだと感じてしまうかと思います。しかし、キモの部分やコツさえ掴んでしまえば魅力的なフレームワークになるのは間違いありません。従来のASP.NETでは手が届かなかった部分に手が届くフレームワークですし、ASP.NET以外のWeb開発者にとってもASP.NET以上に利用しやすいフレームワークだと言えます。
ASP.NET開発者は新たな選択肢の1つとして、ASP.NET MVCも知っておくとよいでしょう。
今回はスキャフォールディング機能を利用して参照、編集、詳細、新規作成ができるアプリケーションを作成しました。基本的なひな形はASP.NET MVCが用意しているので、開発者はControllerに注力すれば簡単にこのアプリケーションが作れることを確認できたかと思います。ただし、今回利用した機能はASP.NET MVC全体から見ると、本当に基本的な部分でしかありません。
次回はAJAX、単体テスト、フィルタの作成といった、実際にサイトを公開する際のエッセンスについて解説します。