hokuriku.net asp.net mvc入門 「実践」 20120825

Post on 28-May-2015

9.640 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

2012/08/25 に開催したASP.NET MVC入門。 ハンズオン形式で、アプリを作成しました。

TRANSCRIPT

ASP.NET MVC 入門 アプリケーション作成

1

以下、ASP.NET MVCを MVCと呼びます。

全体像

2

HTTPリクエスト

HTTPレスポンス

Controlller

View

Model

3

9月末に、Hokuriku.NET vol.10 が開催されるということで、 セッション・アンケート管理のWEBアプリを 作成します。

プロジェクト作成

・新しいプロジェクト>ASP.NET MVC 4 WEB アプリケーション ・プロジェクトの名前を入力し、「OK」ボタン

プロジェクト作成

・テンプレートを選択します。 ・ビューエンジンを選択します。 ・Razor ←今日はこれを選択。 ・ASPX

ビューエンジンの選択について Viewを作成するときの構文 を選択します。 ASPX WEBフォームでの構文を記載 できます。 往来のスキルを活かせます。 Razor MVC3から追加されたもの。 タイピング数が少なくて楽 なので、Razorがオススメ。

プロジェクト構成

Controllerクラスの場所 Controllers名前空間に属すこと。

MVCプロジェクト以外のプロジェクトでも良いが、その場合はプロジェクト参照設定を 忘れない。

Controllerクラス クラス名は「~~Controller」と、最後にControllerをつける。 Controllerクラスを継承する。

Viewファイルの場所

MVCプロジェクト配下のViewsフォルダの中に配置する。 Viewsファイルは、対応するControllerの名前のフォルダか、Sharedフォルダに配置。

MVCは、「規約は設定に勝る」というコンセプトに基づいているため、 命名規則など、あらかじめ決められていることがあります。 (開発者が変更できるところとできないところがあります。) プロジェクト構成も、決められていることがあります。

7

URL HTTPメソッド 目的

/Session/List GET セッション一覧を表示する

一覧取得画面の流れを確認

GET /Session/List

一覧画面のHtml

アクセス

セッション一覧

SessionControllerクラスを作成します。 一覧の処理を実装する、アクションメソッドを作成します。

public ActionResult List() {

return View(); }

次に、一覧のViewを作成します。

デバッグし、/Session/List にアクセスします。

フレームワーク

URL /Session/List

SessionControllerクラス インスタンス化

SessionControllerクラスの Listメソッド実行

List.csHtml より Htmlを出力

ASP.NET MVC

フレームワーク

ルーティング初期設定

URL /Session/List

SessionControllerクラスの Listメソッド

なぜ、/Session/List が SessionControllerクラスのListメソッド紐づいたか? RouteConfig.cs(またはGlobal.asax)にて、 そのように初期設定されている。

→ルーティング という機能ですが、このルーティングについては後程。

ルーティングの初期設定 /コントローラ名/アクションメソッド名/(ID)

アクションメソッド

アクションメソッド コントローラクラスの中に定義するメソッドです。 MVCのうちのコントローラの部分の処理を実装しているところです。 ユーザからのリクエストを、処理し、Viewを呼び出します。 基本的には、戻り値として、ActionResultクラスを返します。

ActionResult アクションメソッドの結果を表す抽象クラスです。 アクションメソッドの結果を表すものは、このクラスを継承しています。 Viewを返す時は、ViewResultクラスを返し、 何かファイルをダウンロードさせたいときは、FileResultを返すなど いろいろな種類があります。

戻り値のヘルパーメソッド

return View(); ActionResultをインスタンス化して、返す処理を、 リファクタリングしたもの。

大体のActionResultを継承しているクラスはこのヘルパーが用意されています。

ActionResultの種類

クラス名 概要 ヘルパーメソッド利用

ContentResult 文字列を出力します return Content(“ya-!”);

ViewResult ビューを出力します return View();

PartialViewResult 部分ビューを出力します return PartialView();

RedirectResult 指定されたURLにリダイレクトします

return Redirect("http://sample.com");

RedirectToRouteResult

指定されたアクションに、リダイレクトします

return RedirectToAction("Create");

FileContentResult ファイルの内容を出力します(バイト配列)

return File(byte[], "image/jpeg");

HttpNotFoundResult 404を返します。 return HttpNotFound();

などなどたくさんあります。

Viewの指定

Return View(); のように、引数に何も指定しない場合は、

または、

Views/コントローラクラス名/アクションメソッドの名前

Views/Shared/アクションメソッドの名前

が呼び出されされます。 Sharedフォルダ内は、すべてのコントローラ共有のViewを格納します。

Viewの指定 2

return View(“Index”); のように文字列を指定すると、Viewの名前を指定できます。

場所は、先ほどと同じように、 Views/コントローラクラス名/Index.csHtml

Views/Shared/Index.csHtml

コントローラクラス名のフォルダ、またはSharedフォルダの中のViewが指定されます。

View/違うコントローラのクラス名/….csHtml

↑のように、違うコントローラのクラス名のフォルダのViewは、 指定できません。

コントローラのインスタンス化

コントローラのコンストラクタの引数に気をつける。

コントローラのインスタンス化は、MVCフレームワークが行うので、 コンストラクタの引数に、int number などを定義すると、 「numberって何いれればいいの?」 とエラーが起きます。

コンストラクタの引数を、開発者が定義し、フレームワークに これ使ってね、と設定することは可能です。

キーワード: Unity, 依存性の注入, カスタムコントローラファクトリー

コントローラの作成をカスタムする

フレームワークが行っているコントローラの作成を、 開発者側で定義した方法で行うよう、定義します。以下は方法の1つです。

カスタムコントローラファクトリーの作成

public class ControllerFactory : DefaultControllerFactory { public override IController CreateController( RequestContext requestContext, string controllerName) { int number = 3; return new SessionController(number); } }

カスタムコントローラファクトリーの登録

Global.asaxにて。 ControllerBuilder.Current.SetControllerFactory(typeof(ControllerFactory));

多くの拡張ポイント

MVCには、このように拡張できるポイントが、いくつもあります。 開発者の自由にカスタマイズできるところが、MVCの特徴でもあります。 (ほとんどはあまり使用されません。)

アクションインボーカー アクションメソッドの実行、レスポンスの制御など

コントローラファクトリー コントローラインンスタンスのファクトリ

ディクショナリ値 リクエストの入力値の読み取り

モデルバインダー ★よく使われる ディクショナリ値から、モデルを生成

モデルバインダープロバイダー モデルバインダーを動的に作成するためのファクトリー

モデルメタデータ モデルのメタ情報の取得と関連付け

モデルバリデータ モデルメタデータの検証特化

TempData TempDataのストレージ

ビューエンジン HTMLを生成する機能をもつコンポーネント。 規定はASPX, Razor

キーワード*セッション一覧

20

HTTPリクエスト

HTTPレスポンス

Controlller

View

Model

実装-アクションメソッド

Viewは指定できる

ActionResultクラス

21

URL HTTPメソッド 目的

/Session/Create GET セッションを作成するための 画面を取得します

POST セッションを新規追加します

作成時の流れを確認

22

GET /Session/Create

作成画面のHtml

POST /Session/Create Title = メトロアプリ作成 & Speaker = 太郎

302 Redirect /Session/List

GET /Session/List

一覧画面のHtml

入力

DB登録

アクセス

一覧画面確認

モデルの作成

タイトル string サブタイトル string 開始時間 datetime 終了時間 datetime 発表者名 string 概要 string 参考URL string

セッションのモデルを作成します。

作成画面取得アクションメソッド

public ActionResult Create() {

return View(); }

一覧画面と同じように作成します。

Viewを作成します。

メソッドの上で右クリック→ビューの追加

<div class="editor-label"> タイトル </div> <div class="editor-field"> @Html.TextBox("Title") </div>

おさらい 送信時の画面のHTML

<form action=“home/create” method=“post”> <input type=“text” name=“Who” value=“Taro” /> <input type=“submit” /> </form>

POSTかGET

送信する名前 と値のペア

Submitボタンを押すと、 Formで囲まれたコントロールの NameとValueの値をペアとして 送信する。 送信するときの、HTTPメソッド は、GETかPOSTの2つのどれか。 GETの場合は、URIのクエリ文字列として、 POSTの場合は、Bodyの値として送信される。

作成画面 Html ヘルパーの利用

<form></form> タグ

@using (Html.BeginForm()) { }

↑だと、現在表示しているURLへ、POSTメソッドで送信します。

@using (Html.BeginForm( “action”, ← 送信先のアクションメソッド名 “controller”, ← 送信先のコントローラ名 new { id = 1 }, ← パラメータの設定 FormMethod.Get, ← GETで送信 new { @class = “form” })) { ← クラス属性の値設定 }

↑のように、たくさんのオプションを設定することもできます。 多くのHtmlヘルパーは、自由にオプションを設定することができます。

作成画面 Html inputタグの作成

<input type=“text”> タグ

@Html.TextBox(“Title”)

name属性の値がTitleである、テキストボックス のHtmlタグを出力します。

<input type=“submit” />は対応するHtmlヘルパーがないのでそのまま。

作成画面の取得の実装は以上です。 /Session/Create にアクセス!

Razor @

@{ var name = “Taro”; }

コードブロック

@if (true) { <span>こんにちは</span> }

if 文やforeach文は、@の後すぐに記述できます。

コメント

@* 出力されません *@

ここで、基本的なRazorの書き方を見てみます。

Razor @

ヘルパーメソッドの利用

@ViewMessage("メッセージ") @helper ViewMessage(string message) { <span>@message</span> }

全て、@から始まる 基本的にHtmlエスケープしてくれます。

マスターページ

マスターページとは

HPへようこそ!

あなたは123番目の お客様です!

HPへようこそ!

自己紹介します! 名前:たろうくん

複数のページにまたがって同じものを描画したい時に使う。

マスターページ

利用方法

マスターページを利用したいViewに記述します。 Layoutにマスタページのパスを指定します。

省略

View/_ViewSart.csHtml に記述したものは、 すべてのページに反映されます。 ので、個別にLayoutを記述しなくてもOK

マスターページ

@RendarBody() (マスターページ)

この場所に、子ページの内容が入ります。

マスターページ

@RenderSection(名前, required) (マスターページ)

RendarBodyの他に、何か埋め込みたいときに記述します。 Requiredは、子ページ側で必ずコンテンツを指定するかどうかです。 デフォルトはtrueで、@RenderSection(“名前”)と書くと、 必ず子ページ側でコンテンツを記述する必要があります。

@Section “名前” { } (子ページ) 子ページ側で、マスターページで RenderSectionと書いた場所に、 コンテンツを埋め込む方法です。 @sectionの後には、名前を指定します。 Requiredがfalseの場合は、記述しなく ても構いません。

キーワード*セッション作成取得

34

HTTPリクエスト

HTTPレスポンス

Controlller

View

Model

マスターページ

Razor記法

Htmlヘルパー

作成画面 POST送信後の処理

POST /Session/Create で送信された時の、アクションメソッドの仕事を確認します。

仕事 送信された値を取得し、データベースを更新する。 更新後、一覧へするようリダイレクトを送信する。

POST /Session/Create Title = メトロアプリ作成 & Speaker = 太郎

302 Redirect /Session/List

入力

DB登録

作成画面 POSTアクションメソッド

public ActionResult CreateRegist() {

return View(); }

一覧画面と同じように作成します。 メソッド名が被るので、CreateRegistにします。

リダイレクトを送信します。同じSessionコントローラのListメソッドを指定します。 すると、MVCフレームワークは、そのアクションメソッドに対応するURLを生成して、リダイレクトを送信してくれます。

return RedirectToAction(“List");

RedirectToActionは、多数の引数を指定可能です。

return RedirectToAction("Index", "Home", new { id = 3 });

作成画面 POSTアクションメソッド

//取得時 public ActionResult Create() {

return View(); } //送信時 [ActionName("Create")] [HttpPost] public ActionResult CreateRegist() {

return View(); }

/Session/CreateでPOST送信すると、上の取得メソッドの方にマッピンングされて

しまいます。送信時の処理を行うのは、下のメソッドなので、2つの属性を追加します。 どちらもActionNameSelectorAttributeを継承しているクラスで、 アクションメソッドの選択に影響する属性です。

作成画面 POSTアクションメソッド

送信された値を取得します。 方法は2つあります。

var title = Request.Form["Title"]; var start = Request.Form["StartTime"];

POST /Session/Create Title = メトロアプリ作成 & SpeakerName = 太郎

① Request.Formで取得

送信されたnameを文字列で指定し、値を取得する方法です。 しかしこれでは、すべてstring型として1つ1つ取得するので、 大変面倒です。一般的にこの方法は利用しません。

作成画面 モデルバインダー

POST /Session/Create Title = メトロアプリ作成 & StartTime = 2012/01/01

そこで登場するのが2つ目の方法、モデルバインダーです。 MVCの主要機能の1つです。

モデルバインダは、フォーム送信データなどのHTTPリクエストの値(文字列)から、 オブジェクト(クラスなど)を生成するプロセスのことです。

作成画面 モデルバインダー

モデルバインダーは、アクションメソッドの引数のオブジェクトに対して、 行われます。 引数に定義するだけで、モデルバインダーが働き、オブジェクトを生成して メソッドに渡してくれます。 Request.Form[“Title”]を使うよりも、session クラスに値が入ってくれれば、 開発者はとても楽になります。

作成画面 モデルバインダー

規定モデルバインダーのバインドルール

定義したクラスの、プロパティ名と同じnameの値がバインドされます。

フォーム送信データ: Title = メトロアプリ作成 & StartTime = 2012/01/01

Session クラス ・Title プロパティ = “メトロアプリ作成” ・StartTime プロパティ = new DateTime(2012, 1, 1)

作成画面 モデルバインダー

規定モデルバインダーのバインドルール 2層

定義したクラスのプロパティが別のクラスの型であっても、バインドできます。 Nameは[プロパティ名] . [プロパティ名]です。(ドットをいれます。)

フォーム送信データ: Title = メトロアプリ作成 & Speaker.Name = 2012/01/01 & Speaker.Location = “Toyama”

作成画面 モデルバインダー

規定モデルバインダーのバインドルール 階層

<input type="text" name="Child.Child.Child. Child.Child.Child.Name"/>

new Product { Child = new Product { Child = new Product { Child = new Product { Child = new Product { Child = new Product { Child = new Product { Name = "MADNESS!" } } } } } } }

極端な話、何階層でも バインドしてくれます。

http://msdn.microsoft.com/ja-jp/magazine/hh781022.aspx より

作成画面 モデルバインダー

規定モデルバインダーのバインドルール コレクション

定義したクラスのプロパティが、コレクションであってもバインドしてくれます。

フォーム送信データ: Title = メトロアプリ作成 & Speakers[0] .Name = “ひとりめ” & Speakers[1] . Name = “ふたりめ”

作成画面 モデルバインダー

規定モデルバインダー 値の取得元

バインドする時に参照する文字列は、フォーム送信だけではなく、 他のHTTPリクエストの値も参照されます。

フォーム送信データ ルートデータ(URLの一部) クエリ文字列(URLの後ろ) 送信されたファイル

作成画面 モデルバインダー

規定モデルバインダー 注意

定義したクラスのコンストラクタに、何か引数が指定している場合は、 規定モデルバインダーは失敗します。 どうしても引数ありのコンストラクタしか使えないのであれば、 独自のモデルバインダーを作成する必要があります。

作成画面 モデルバインダー

まとめ POST /Session/Create Title = メトロアプリ作成 & StartTime = 2012/01/01

HTTPリクエストの内容を、文字列ではなく オブジェクトとして扱いやすくするために 利用する。

アクションメソッドの引数に定義されたものを バインドしてくれる。

規定のモデルバイダーが動くが、独自の モデルバインダーを設定することができる。

バインドしやすいように、送信するnameを 制御するとよい。(方法については後程)

作成画面 POSTアクションメソッド

実装に戻ります。 送信された値を取得するため、モデルバインダーを利用します。 メソッドの引数にSessionを定義します。 そのSessionでDBを更新します。 デバッグ! DBに追加されたかを確認します。 ・・・開始日や終了日に何も入力しないと、コミット時にエラーが起きるはずです。

作成画面 検証時の流れ

データを作成するときは、値が適切になるよう、検証する必要があります。 そして、ユーザに「この値は必ず入力してください」などと、伝える必要があります。 検証を実装する前に、 この時のHTTP通信の流れはどうなるのか?確認します。

データ この値じゃだめだよ!

作成画面 検証時の流れを確認

50

作成画面のHtml

POST /Session/Create Title = (空)& Speaker = 太郎

GET /Session/List

修正して送信!

検証失敗

送信!

POST /Session/Create Title = タイトルやで& Speaker = 太郎

成功 リダイレクト

+ユーザが入力した値を 表示するHtml

+検証失敗の理由を 表示するHtml

作成画面 検証の実装

51

検証の実装は、とても簡単です。 ①モデルに、検証属性を追加します。

作成画面 検証の実装

52

②Viewに検証メッセージを表示するようにします。

作成画面 検証の実装

53

③POST時のアクションメソッドで、検証に失敗した場合は、 入力情報があるsessionをViewに渡し、表示させます。 検証が成功した場合は、リダイレクトを送信します。

検証機能の実装は以上です。デバッグ!

作成画面 検証の実装

54

モデルバインダーにて、Sessionクラスを生成するときに、 属性の情報を元に検証を行い、 ModelStateにエラー情報を格納しています。 また、ModelStateには、新たにエラー情報を追加することもできます。

しくみ

55

データ

今実装したのは、サーバ側で検証する処理です。 WEBアプリでは、サーバ側の他に、クライアント側で検証する方法があります。 クライアント側で行う利点は、

不要な通信が減る レスポンスが早い の2つがあります。 クライアント側の検証はJavaScriptとHtmlで行います。

ブラウザ上で検証 Javascript

サーバで検証

検証 クライアント側・サーバ側

検証 クライアント検証

56

データ

ブラウザ上で検証 Javascript

クライアント検証 注意

クライアント側だけで検証するのは控えてください。 クライアント側の処理なので、ユーザ側は自由に検証をOFFにすることができます。 (JavaScriptをOFFにしたり、ブラウザ以外で通信したり) ですので、サーバ側の検証は必ず実装してください。

無防備なり

検証 クライアント検証 実装

クライアンド検証の実装も簡単です。 ①WebConfigの設定

<appSettings> <add key="ClientValidationEnabled" value="true" /> <add key="UnobtrusiveJavaScriptEnabled" value="true" /> </appSettings>

クライアント検証を有効にするかどうかと、 控え目なJavaScriptを有効にすうるかどうかの2つの値をtrueにします。 (デフォルトで既にそうなっています。) ↓のようにページに記述し、ページ単位で制御することも可能です。

@{ Html.EnableClientValidation(); Html.EnableUnobtrusiveJavaScript(); }

検証 クライアント検証 実装

②JavaScriptのスクリプトファイルの読み込み

検証を実装しているクスリプトファイルを読み込むよう設定します。 各ページ、またはマスタページや_ViewStart.csHtmlに記述します。

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

MVC4のテンプレートの場合は、以下のように記述できます。

@Scripts.Render("~/bundles/jqueryval")

(BundleConfig.csで上記2つのファイルを読み込むよう設定してあります。)

検証 クライアント検証 実装

③Htmlヘルパーの変更

作成画面のViewに、下のコードを追加し、型情報よりView を記述できるようにします。

@model HokurikuMvc.Models.Session

@Html.TextBox(“Title”) @Html.ValidationMessage(“Tite”)

@Html.TextBoxFor(m => m.Title) @Html.ValidationMessageFor(m => m.Title)

また、このコードを、

これにより、検証属性の情報から、検証できるようHtmlタグが出力されます。 デバッグで、ソースを確認してみます。

下のように変更します。

検証 他

他、クライアントサイドの検証については

非同期でサーバと通信し、検証を行うリモート検証や、

独自の検証を実装する、カスタム検証があります。 また、複数の値でから検証を行うこともできます。(CustomValidation)

キーワード*セッション作成送信

61

HTTPリクエスト

HTTPレスポンス

Controlller

View

Model

エラーメッセージの表示

クライアント検証ができるように、 Htmlヘルパーを利用

モデルバインダ 検証

クライアント検証 (JavaScript)

ASP.NET MVC アプリケーション作成

ここで時間オーバーにより

終了…

お疲れ様でした。

62

top related