Razor と控えめな JavaScript で MVC 3 を作成する

提供元: Microsoft

このユーザー リストのサンプル Web アプリケーションでは、Razor ビュー エンジンを使用して ASP.NET MVC 3 アプリケーションを簡単に作成する方法を示しています。 このサンプル アプリケーションでは、新しい Razor ビュー エンジンを ASP.NET MVC 3 バージョン 3 および Visual Studio 2010 と一緒に使用して、ユーザーの作成、表示、編集、削除などの機能を含む架空のユーザー リスト Web サイトを作成する方法を示します。

このチュートリアルでは、ユーザー リスト サンプル ASP.NET MVC 3 アプリケーションを構築するために実行された手順について説明します。 このトピックで使用されている Visual Studio プロジェクトと C# および VB ソース コードをダウンロードできます。 このチュートリアルについて質問がある場合は、MVC フォーラムに投稿してください。

概要

ここで構築するアプリケーションは、単純なユーザー リスト Web サイトです。 ユーザーは、ユーザー情報を入力、表示、更新できます。

Sample site

VB と C# の完成したプロジェクトは、ここでダウンロードできます。

Web アプリケーションの作成

このチュートリアルを開始するには、Visual Studio 2010 を開き、ASP.NET MVC 3 Web アプリケーション テンプレートを使用して、新しいプロジェクトを作成します。 アプリケーションに "Mvc3Razor" という名前を付けます。

New MVC 3 project

[新しい ASP.NET MVC 3 プロジェクト] ダイアログで、[インターネット アプリケーション] を選択し、Razor ビュー エンジンを選択して、[OK] をクリックします。

New ASP.NET MVC 3 Project dialog

このチュートリアルでは、ASP.NET メンバーシップ プロバイダーを使用しないため、ログオンとメンバーシップに関連付けられているすべてのファイルを削除できます。 ソリューション エクスプローラーで、次のファイルとディレクトリを削除します。

  • Controllers\AccountController
  • Models\AccountModels
  • Views\Shared\_LogOnPartial
  • Views\Account (およびこのディレクトリ内のすべてのファイル)

Soln Exp

_Layout.cshtml ファイルを編集し、<div> 要素内の logindisplay という名前のマークアップを "Login Disabled" というメッセージで置き換えます。 次の例は、新しいマークアップを示しています。

<div id="logindisplay">
  Login Disabled
</div>

モデルの追加

ソリューション エクスプローラーで、Models フォルダーを右クリックし、[追加] を選択し、[クラス] を選択します。

New User Mdl class

クラスに UserModel という名前を付けます。 UserModel ファイルの内容を次のコードに置き換えます。

using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;

namespace Mvc3Razor.Models {
    public class UserModel {

        [Required]
        [StringLength(6, MinimumLength = 3)]
        [Display(Name = "User Name")]
        [RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed")]
        [ScaffoldColumn(false)]
        public string UserName { get; set; }

        [Required]
        [StringLength(8, MinimumLength = 3)]
        [Display(Name = "First Name")]
        public string FirstName { get; set; }
        [Required]
        [StringLength(9, MinimumLength = 2)]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }
        [Required()]
        public string City { get; set; }

    }

    public class Users {

        public Users() {
            _usrList.Add(new UserModel
            {
                UserName = "BenM",
                FirstName = "Ben",
                LastName = "Miller",
                City = "Seattle"
            });
            _usrList.Add(new UserModel
            {
                UserName = "AnnB",
                FirstName = "Ann",
                LastName = "Beebe",
                City = "Boston"
            });
        }

        public List<UserModel> _usrList = new List<UserModel>();

        public void Update(UserModel umToUpdate) {

            foreach (UserModel um in _usrList) {
                if (um.UserName == umToUpdate.UserName) {
                    _usrList.Remove(um);
                    _usrList.Add(umToUpdate);
                    break;
                }
            }
        }

        public void Create(UserModel umToUpdate) {
            foreach (UserModel um in _usrList) {
                if (um.UserName == umToUpdate.UserName) {
                    throw new System.InvalidOperationException("Duplicat username: " + um.UserName);
                }
            }
            _usrList.Add(umToUpdate);
        }

        public void Remove(string usrName) {

            foreach (UserModel um in _usrList) {
                if (um.UserName == usrName) {
                    _usrList.Remove(um);
                    break;
                }
            }
        }

        public  UserModel GetUser(string uid) {
            UserModel usrMdl = null;

            foreach (UserModel um in _usrList)
                if (um.UserName == uid)
                    usrMdl = um;

            return usrMdl;
        }

    }    
}

UserModel クラスはユーザーを表します。 クラスの各メンバーには、DataAnnotations 名前空間の Required 属性で注釈が付けられます。 DataAnnotations 名前空間の属性は、Web アプリケーションのクライアント側とサーバー側の自動検証を提供します。

HomeController クラスを開き、UserModel クラスと Users クラスにアクセスできるように、using ディレクティブを追加します。

using Mvc3Razor.Models;

HomeController 宣言の直後に、次のコメントと Users クラスへの参照を追加します。

public class HomeController : Controller {

// The __usrs class is replacement for a real data access strategy.
private static Users _usrs = new Users();

Users クラスは、このチュートリアルで使用する簡略化されたメモリ内データ ストアです。 実際のアプリケーションでは、データベースを使用してユーザー情報を格納します。 次の例では、HomeController ファイルの最初の数行を示します。

using System.Web.Mvc;
using Mvc3Razor.Models;

namespace Mvc3Razor.Controllers {
       
    public class HomeController : Controller {

        // The __usrs class is replacement for a real data access strategy.
        private static Users _usrs = new Users();

次の手順でユーザー モデルをスキャフォールディング ウィザードで使用できるように、アプリケーションをビルドします。

既定のビューの作成

次の手順では、アクション メソッドとビューを追加してユーザーを表示します。

既存の Views\Home\Index ファイルを削除します。 ユーザーを表示するための新しい Index ファイルを作成します。

HomeController クラスで、Index メソッドの内容を次のコードに置き換えます。

return View(_usrs._usrList);

Index メソッド内を右クリックし、[ビューの追加] をクリックします。

Add View

[厳密に型指定されたビューを作成する] オプションを選択します。 [View data class]\(ビュー データ クラス\) に対し、Mvc3Razor.Models.UserModel を選択します。 ([View data class]\(ビュー データ クラス\) ボックスに Mvc3Razor.Models.UserModel が表示されない場合は、プロジェクトをビルドする必要があります)。ビュー エンジンが Razor に設定されていることを確認します。 [コンテンツの表示][リスト] に設定し、[追加] を選択します。

Add Index View

新しいビューは、Index ビューに渡されたユーザー データを自動的にスキャフォールディングします。 新しく生成された Views\Home\Index ファイルを調べます。 [新規作成][編集][詳細][削除] の各リンクは機能しませんが、ページの残りの部分は機能します。 このページを実行します。 ユーザーの一覧が表示されます。

Index Page

Index.cshtml ファイルを開き、[編集][詳細][削除]ActionLink マークアップを次のコードに置き換えます。

@Html.ActionLink("Edit", "Edit", new {  id=item.UserName  }) |
@Html.ActionLink("Details", "Details", new {  id=item.UserName  }) |
@Html.ActionLink("Delete", "Delete", new {  id=item.UserName  })

ユーザー名は、[編集][詳細][削除] リンクで選択したレコードを検索するための ID として使用されます。

詳細ビューの作成

次の手順では、ユーザーの詳細を表示するために Details アクション メソッドとビューを追加します。

Screenshot shows the Details Fields with UserName, FirstName, LastName, and City for a user.

次の Details メソッドをホーム コントローラーに追加します。

public ViewResult Details(string id) {
    return View(_usrs.GetUser(id));
}

Details メソッド内を右クリックし、[ビューの追加] を選択します。 [View data class]\(ビュー データ クラス\) ボックスに Mvc3Razor.Models.UserModel が含まれていることを確認します。[コンテンツの表示][詳細] に設定し、[追加] をクリックします。

Add details view

アプリケーションを実行し、詳細リンクを選択します。 自動スキャフォールディングでは、モデル内の各プロパティが表示されます。

Screenshot shows the Details Fields with values for a user.

編集ビューの作成

次の Edit メソッドをホーム コントローラーに追加します。

public ViewResult Edit(string id) {
    return View(_usrs.GetUser(id));
}

[HttpPost]
public ViewResult Edit(UserModel um) {

    if (!TryUpdateModel(um)) {
        ViewBag.updateError = "Update Failure";
        return View(um);
    }

    // ToDo: add persistent to DB.
    _usrs.Update(um);
    return View("Details", um);
}

前の手順と同様にビューを追加しますが、[コンテンツの表示][編集] に設定します。

Add Edit view

アプリケーションを実行し、いずれかのユーザーの姓と名を編集します。 UserModel クラスに適用されている DataAnnotation 制約に違反した場合、フォームを送信すると、サーバー コードによって生成される検証エラーが表示されます。 たとえば、名 "Ann" を "A" に変更した場合、フォームを送信すると、フォームに次のエラーが表示されます。

The field First Name must be a string with a minimum length of 3 and a maximum length of 8.

このチュートリアルでは、ユーザー名を主キーとして扱います。 そのため、ユーザー名プロパティを変更することはできません。 Edit.cshtml ファイルで、Html.BeginForm ステートメントの直後に、ユーザー名を非表示フィールドに設定します。 これにより、プロパティがモデルに渡されます。 次のコード フラグメントは、Hidden ステートメントの配置を示しています。

<h2>Edit</h2>
    @using (Html.BeginForm()) {
@Html.Hidden("UserName", Model.UserName)

ユーザー名の TextBoxForValidationMessageFor マークアップを DisplayFor 呼び出しに置き換えます。 DisplayFor メソッドは、プロパティを読み取り専用要素として表示します。 完全なマークアップの例を次に示します。 元の TextBoxFor 呼び出しと ValidationMessageFor 呼び出しは、Razor begin-comment 文字と end-comment 文字 (@* *@) でコメントアウトされています。

<div class="editor-label">
  @Html.LabelFor(model => model.UserName)
</div>

<div class="editor-field">
@*
  @Html.TextBoxFor(model => model.UserName)
  @Html.ValidationMessageFor(model => model.UserName)
*@
@Html.DisplayFor(model => model.UserName)
</div>

クライアント側検証の有効化

ASP.NET MVC 3 でクライアント側の検証を有効にするには、2 つのフラグを設定する必要があり、3 つの JavaScript ファイルを含める必要があります。

アプリケーションの Web.config ファイルを開きます。 アプリケーション設定で that ClientValidationEnabledUnobtrusiveJavaScriptEnabled が true に設定されていることを確認します。 ルート Web.config ファイルの次のフラグメントは、正しい設定を示しています。

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

UnobtrusiveJavaScriptEnabled を true に設定すると、控えめな Ajax と控えめなクライアント検証が有効になります。 控えめな検証を使用すると、検証規則は HTML5 属性に変換されます。 HTML5 属性名は、小文字、数字、ダッシュのみで構成できます。

ClientValidationEnabled を true に設定すると、クライアント側の検証が有効になります。 これらのキーを Web.config ファイル アプリケーションで設定することで、アプリケーション全体に対してクライアント検証と控えめな JavaScript を有効にします。 次のコードを使用して、個々のビューまたはコントローラー メソッドでこれらの設定を有効または無効にすることもできます。

HtmlHelper.ClientValidationEnabled = true; 
HtmlHelper.UnobtrusiveJavaScriptEnabled = true;

また、レンダリングされたビューにいくつかの JavaScript ファイルを含める必要があります。 すべてのビューに JavaScript を含める簡単な方法は、それらを Views\Shared\_Layout.cshtml ファイルに追加することです。 _Layout.cshtml ファイルの <head> 要素を、次のコードに置き換えます。

<head>
  <title>@View.Title</title>
  <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
  <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.4.2.min.js"></script>
  <script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.7/jquery.validate.min.js"></script>
  <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
</head>

最初の 2 つの jQuery スクリプトは、Microsoft Ajax Content Delivery Network (CDN) によってホストされます。 Microsoft Ajax CDN を利用すると、アプリケーションの初回ヒットのパフォーマンスを大幅に向上させることができます。

アプリケーションを実行し、編集リンクをクリックします。 ブラウザーでページのソースを表示します。 ブラウザー ソースは、フォーム data-val の多くの属性を示しています (データ検証用)。 クライアント検証と控えめな JavaScript が有効になっている場合、クライアント検証規則を持つ入力フィールドには、控えめなクライアント検証をトリガーする data-val="true" 属性が含まれます。 たとえば、モデル内の City フィールドは Required 属性で修飾され、その結果、次の例に示す HTML が表示されます。

<div class="editor-field">
  <input data-val="true" data-val-required="The City field is required." id="City" name="City" type="text" value="Seattle" />
  <span class="field-validation-valid" data-valmsg-for="City" data-valmsg-replace="true"></span>
</div>

クライアント検証規則ごとに、フォーム data-val-rulename="message" を持つ属性が追加されます。 前に示した City フィールドの例を使用して、必要なクライアント検証規則によって data-val-required 属性と "The City field is required" というメッセージが生成されます。 アプリケーションを実行し、いずれかのユーザーを編集して、City フィールドをクリアします。 Tab キーを押してフィールドから外に移動すると、クライアント側の検証エラー メッセージが表示されます。

City required

同様に、クライアント検証規則の各パラメーターに対して、フォーム data-val-rulename-paramname=paramvalue を持つ属性が追加されます。 たとえば、FirstName プロパティには StringLength 属性で注釈が付けられ、最小長 3、最大長 8 を指定します。 length という名前のデータ検証規則には、パラメーター名 max とパラメーター値 8 があります。 次に、いずれかのユーザーを編集するときに、FirstName フィールドに対して生成される HTML を示します。

<input data-val="true"         
       data-val-length="The field First Name must be a string with a minimum length of 3 and a maximum length of 8." 
       data-val-length-max="8" 
       data-val-length-min="3" 
       data-val-required="The First Name field is required." 
       id="FirstName" 
       name="FirstName" 
       type="text" 
       value="Ben" />

控えめなクライアント検証の詳細については、Brad Wilson のブログの「ASP.NET MVC 3 での控えめなクライアントの検証」エントリを参照してください。

Note

ASP.NET MVC 3 ベータ版では、クライアント側の検証を開始するためにフォームを送信する必要がある場合があります。 これは、最終リリースで変更される可能性があります。

作成ビューの作成

次の手順では、Create アクション メソッドとビューを追加して、ユーザーが新しいユーザーを作成できるようにします。 次の Create メソッドをホーム コントローラーに追加します。

public ViewResult Create() {
    return View(new UserModel());
}

[HttpPost]
public ViewResult Create(UserModel um) {

    if (!TryUpdateModel(um)) {
        ViewBag.updateError = "Create Failure";
        return View(um);
    }

    // ToDo: add persistent to DB.
    _usrs.Create(um);
    return View("Details", um);
}

前の手順と同様にビューを追加しますが、[コンテンツの表示][作成] に設定します。

Create View

アプリケーションを実行し、[作成] リンクを選択して、新しいユーザーを追加します。 Create メソッドは、クライアント側とサーバー側の検証を自動的に利用します。 "Ben X" などの空白を含むユーザー名を入力してみてください。 Tab キーを押してユーザー名フィールドから外に移動すると、クライアント側の検証エラー (White space is not allowed) が表示されます。

Delete メソッドの追加

このチュートリアルを完了するには、次の Delete メソッドをホーム コントローラーに追加します。

public ViewResult Delete(string id) {
    return View(_usrs.GetUser(id));
}

[HttpPost]
public RedirectToRouteResult Delete(string id, FormCollection collection) {
    _usrs.Remove(id);
    return RedirectToAction("Index");
}

前の手順と同様に Delete ビューを追加し、[コンテンツの表示][削除] に設定します。

Delete View

これで、検証機能を備えたシンプルで完全に機能する ASP.NET MVC 3 アプリケーションが作成されました。