ASP.NET Core のフォームのタグ ヘルパー
作成者: Rick Anderson、N. Taylor Mullen、Dave Paquette、Jerrie Pelser
このドキュメントでは、フォームとフォームでよく使用される HTML 要素の使用方法について説明します。 HTML の Form 要素には、Web アプリケーションからサーバーにデータをポスト バックするために使用する主要なメカニズムがあります。 このドキュメントでは、タグ ヘルパーと、タグ ヘルパーを利用して堅牢な HTML フォームを生産的に作成する方法について主に説明します。 このドキュメントを読む前に、タグ ヘルパーの概要に関するページを読むことをお勧めします。
多くの場合、HTML ヘルパーでは特定のタグ ヘルパーの代替方法が提供されますが、タグ ヘルパーを HTML ヘルパーの代わりに使用することはできないことと、各 HTML ヘルパーに対応するタグ ヘルパーがないことを認識することが重要です。 HTML ヘルパーの代替が存在する場合は記載します。
フォーム タグ ヘルパー
MVC コントローラー アクションまたは名前付きルートの HTML <FORM>
action
属性を生成するクロスサイト リクエスト フォージェリを防ぐために、非表示の要求検証トークンを生成します (HTTP POST アクション メソッドで
[ValidateAntiForgeryToken]
属性と共に使用する場合)asp-route-<Parameter Name>
属性を提供します (<Parameter Name>
がルート値に追加される場合)。Html.BeginForm
およびHtml.BeginRouteForm
にrouteValues
パラメーターを指定すると、同様の機能が提供されます。HTML ヘルパーの代替の
Html.BeginForm
とHtml.BeginRouteForm
があります
サンプル:
<form asp-controller="Demo" asp-action="Register" method="post">
<!-- Input and Submit elements -->
</form>
上記のフォーム タグ ヘルパーで、次の HTML が生成されます。
<form method="post" action="/Demo/Register">
<!-- Input and Submit elements -->
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
MVC ランタイムで、フォーム タグ ヘルパーの属性 asp-controller
と asp-action
から action
属性値が生成されます。 また、フォーム タグ ヘルパーも、クロスサイト リクエスト フォージェリを防ぐために、非表示の要求検証トークンを生成します (HTTP POST アクション メソッドで [ValidateAntiForgeryToken]
属性と共に使用する場合)。 純粋な HTML フォームをクロスサイト リクエスト フォージェリから保護することは難しいため、フォーム タグ ヘルパーが提供するサービスを利用してください。
名前付きのルートの使用
asp-route
タグ ヘルパー属性で、HTML action
属性のマークアップを生成することもできます。 register
という名前のルートを持つアプリケーションは、登録ページに次のマークアップを使用できます:
<form asp-route="register" method="post">
<!-- Input and Submit elements -->
</form>
Views/Account フォルダー (個々のユーザー アカウントを使用して新しい Web アプリケーションを作成するときに生成されるフォルダー) のビューの多くには、asp-route-returnurl 属性が含まれています。
<form asp-controller="Account" asp-action="Login"
asp-route-returnurl="@ViewData["ReturnUrl"]"
method="post" class="form-horizontal" role="form">
Note
承認済みで認証されていないリソースまたは承認されていないリソースにアクセスしようとすると、組み込みのテンプレートを使用して、returnUrl
のみが自動的に設定されます。 未承認のアクセスを試行すると、セキュリティ ミドルウェアによって、returnUrl
が設定されたログイン ページにリダイレクトされます。
フォーム アクション タグ ヘルパー
フォーム アクション タグ ヘルパーにより、生成された<button ...>
または <input type="image" ...>
タグ上に formaction
属性が生成されます。 formaction
属性では、フォームがそのデータを送信する場所を制御します。 これは、型が image
の <入力> 要素と、<ボタン> 要素にバインドされます。 フォーム アクション タグ ヘルパーにより、AnchorTagHelper の asp-
属性を複数使うことが可能になり、対応する要素に向けて何の formaction
リンクが生成されるかを制御できます。
formaction
の値を制御するためにサポートされている AnchorTagHelper 属性:
属性 | 説明 |
---|---|
asp-controller | コントローラーの名前。 |
asp-action | アクション メソッドの名前です。 |
asp-area | 領域の名前です。 |
asp-page | Razor ページの名前。 |
asp-page-handler | Razor ページ ハンドラーの名前。 |
asp-route | ルートの名前。 |
asp-route-{value} | 単一の URL ルート値です。 たとえば、「 asp-route-id="1234" 」のように入力します。 |
asp-all-route-data | すべてのルート値です。 |
asp-fragment | URL フラグメントです。 |
コントローラーに送信する例
次のマークアップでは、入力またはボタンが選択されたときに、HomeController
の Index
アクションにフォームを送信します。
<form method="post">
<button asp-controller="Home" asp-action="Index">Click Me</button>
<input type="image" src="..." alt="Or Click Me" asp-controller="Home"
asp-action="Index">
</form>
以前のマークアップでは次の HTML が生成されます。
<form method="post">
<button formaction="/Home">Click Me</button>
<input type="image" src="..." alt="Or Click Me" formaction="/Home">
</form>
ページに送信する例
次のマークアップでは、About
Razor Pages にフォームを送信します:
<form method="post">
<button asp-page="About">Click Me</button>
<input type="image" src="..." alt="Or Click Me" asp-page="About">
</form>
以前のマークアップでは次の HTML が生成されます。
<form method="post">
<button formaction="/About">Click Me</button>
<input type="image" src="..." alt="Or Click Me" formaction="/About">
</form>
ルートに送信する例
/Home/Test
エンドポイントを検討します。
public class HomeController : Controller
{
[Route("/Home/Test", Name = "Custom")]
public string Test()
{
return "This is the test page";
}
}
次のマークアップでは、/Home/Test
エンドポイントにフォームを送信します。
<form method="post">
<button asp-route="Custom">Click Me</button>
<input type="image" src="..." alt="Or Click Me" asp-route="Custom">
</form>
以前のマークアップでは次の HTML が生成されます。
<form method="post">
<button formaction="/Home/Test">Click Me</button>
<input type="image" src="..." alt="Or Click Me" formaction="/Home/Test">
</form>
入力タグ ヘルパー
Input タグ ヘルパーは、HTML の<入力>要素を razor ビューのモデル式にバインドします。
構文:
<input asp-for="<Expression Name>">
入力タグ ヘルパー:
asp-for
属性で指定された式の名前のid
およびname
HTML 属性を生成します。asp-for="Property1.Property2"
はm => m.Property1.Property2
と等価です。 式の名前は、asp-for
属性値に使用されるものです。 詳細については、「式の名前」セクションを参照してください。モデル プロパティに適用されているモデル型とデータ注釈に基づいて HTML の
type
属性値を設定しますHTML
type
属性値が指定されている場合は、上書きしませんHtml.TextBoxFor
およびHtml.EditorFor
と重複する HTML ヘルパー機能があります。 詳細については、「入力タグ ヘルパーの代替となる HTML ヘルパー」セクションを参照してください。厳密な型指定を提供します。 プロパティの名前が変更され、タグ ヘルパーを更新しない場合は、次のようなエラーが表示されます。
An error occurred during the compilation of a resource required to process this request. Please review the following specific error details and modify your source code appropriately. Type expected 'RegisterViewModel' does not contain a definition for 'Email' and no extension method 'Email' accepting a first argument of type 'RegisterViewModel' could be found (are you missing a using directive or an assembly reference?)
Input
タグ ヘルパーは、.NET 型に基づいて HTML type
属性を設定します。 次の表は、一般的な.NET 型と生成される HTML 型の一部をまとめたものです (すべての .NET 型を網羅した一覧ではありません)。
.NET 型 | 入力タイプ |
---|---|
Bool | type="checkbox" |
String | type="text" |
DateTime | type="datetime-local" |
Byte | type="number" |
int | type="number" |
Single、Double | type="number" |
次の表は、入力タグ ヘルパーが特定の入力の型にマップする一般的なデータ注釈属性の一部をまとめたものです (すべての検証属性を網羅した一覧ではありません)。
属性 | 入力タイプ |
---|---|
[EmailAddress] | type="email" |
[Url] | type="url" |
[HiddenInput] | type="hidden" |
[Phone] | type="tel" |
[DataType(DataType.Password)] | type="password" |
[DataType(DataType.Date)] | type="date" |
[DataType(DataType.Time)] | type="time" |
サンプル:
using System.ComponentModel.DataAnnotations;
namespace FormsTagHelper.ViewModels
{
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email Address")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
}
}
@model RegisterViewModel
<form asp-controller="Demo" asp-action="RegisterInput" method="post">
<label>Email: <input asp-for="Email" /></label> <br />
<label>Password: <input asp-for="Password" /></label><br />
<button type="submit">Register</button>
</form>
上記のコードで、次の HTML が生成されます。
<form method="post" action="/Demo/RegisterInput">
Email:
<input type="email" data-val="true"
data-val-email="The Email Address field is not a valid email address."
data-val-required="The Email Address field is required."
id="Email" name="Email" value=""><br>
Password:
<input type="password" data-val="true"
data-val-required="The Password field is required."
id="Password" name="Password"><br>
<button type="submit">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
Email
および Password
プロパティに適用されたデータ注釈によって、モデルに関するメタデータが生成されます。 入力タグ ヘルパーはモデルのメタデータを使用し、HTML5 の data-val-*
属性を生成します (モデルの検証に関するページを参照してください)。 これらの属性に、入力フィールドにアタッチする検証コントロールを記述します。 これで、控えめな HTML5 と jQuery の検証機能を提供します。 控えめな属性の形式は data-val-rule="Error Message"
です。ここで、rule は検証規則の名前 (data-val-required
、data-val-email
、data-val-maxlength
など) です。属性にエラー メッセージが指定されている場合は、data-val-rule
属性の値として表示されます。 data-val-maxlength-max="1024"
など、ルールに関する追加の詳細情報を提供するフォームの属性 data-val-ruleName-argumentName="argumentValue"
もあります。
複数の input
コントロールを同じプロパティにバインドすると、生成されたコントロールは同じ id
を共有するため、生成されたマークアップは無効になります。 重複を防ぐには、各コントロールの id
属性を明示的に指定します。
チェックボックスの非表示入力の表示
HTML5 のチェックボックスでは、オフになったときに値を送信しません。 オフになったチェックボックスについて既定値を送信できるようにするために、入力タグ ヘルパーによって、チェックボックスの追加の非表示入力が生成されます。
たとえば、IsChecked
ブール型モデル プロパティに入力タグヘルパーを使用する次の Razor マークアップについて考えてみます。
<form method="post">
<input asp-for="@Model.IsChecked" />
<button type="submit">Submit</button>
</form>
上記の Razor マークアップでは、次のような HTML マークアップが生成されます。
<form method="post">
<input name="IsChecked" type="checkbox" value="true" />
<button type="submit">Submit</button>
<input name="IsChecked" type="hidden" value="false" />
</form>
上記の HTML マークアップには、IsChecked
という名前の追加の非表示入力と、false
の値が表示されます。 既定では、この非表示入力はフォームの最後に表示されます。 フォームが送信されたとき、次のようになります。
IsChecked
チェックボックスの入力をオンにすると、true
とfalse
の両方が値として送信されます。IsChecked
チェックボックスの入力をオフにすると、非表示の入力値false
のみが送信されます。
ASP.NET Core モデルバインド プロセスは、bool
値にバインドするときに最初の値のみを読み取ります。これにより、チェックボックスがオンの場合は true
になり、チェックボックスがオフの場合は false
になります。
非表示入力の表示の動作を構成するには、MvcViewOptions.HtmlHelperOptions で CheckBoxHiddenInputRenderMode プロパティを設定します。 次に例を示します。
services.Configure<MvcViewOptions>(options =>
options.HtmlHelperOptions.CheckBoxHiddenInputRenderMode =
CheckBoxHiddenInputRenderMode.None);
上記のコードでは、CheckBoxHiddenInputRenderMode
を CheckBoxHiddenInputRenderMode.None に設定することにより、チェックボックスの非表示入力の表示を無効にします。 使用可能なすべての表示モードについては、CheckBoxHiddenInputRenderMode 列挙型を参照してください。
入力タグ ヘルパーの代替となる HTML ヘルパー
Html.TextBox
、Html.TextBoxFor
、Html.Editor
、Html.EditorFor
には、入力タグ ヘルパーと重複する機能があります。 入力タグ ヘルパーでは type
属性が自動的に設定されますが、Html.TextBox
と Html.TextBoxFor
では自動設定されません。 Html.Editor
と Html.EditorFor
はコレクション、複雑なオブジェクト、テンプレートを処理しますが、入力タグ ヘルパーは処理しません。 Input タグ ヘルパーの Html.EditorFor
と Html.TextBoxFor
は厳密に型指定されていますが (ラムダ式を使用します)、Html.TextBox
と Html.Editor
は厳密に型指定されていません (式の名前を使用します)。
HtmlAttributes
@Html.Editor()
と @Html.EditorFor()
は、既定のテンプレートを実行するときに htmlAttributes
という名前の特殊な ViewDataDictionary
エントリを使用します。 この動作は、必要に応じて additionalViewData
パラメーターを使用して拡張されます。 キー "htmlAttributes" は大文字と小文字が区別されません。 キー "htmlAttributes" は、htmlAttributes
のような入力ヘルパーに渡される @Html.TextBox()
オブジェクトと同様に処理されます。
@Html.EditorFor(model => model.YourProperty,
new { htmlAttributes = new { @class="myCssClass", style="Width:100px" } })
式の名前
asp-for
属性値は ModelExpression
であり、ラムダ式の右辺です。 そのため、生成されるコードで asp-for="Property1"
は m => m.Property1
になります。したがって、Model
をプレフィックスとして付加する必要はありません。 "@" 文字を使用してインライン式を開始し、m.
の前に移動できます。
@{
var joe = "Joe";
}
<input asp-for="@joe">
以下が生成されます。
<input type="text" id="joe" name="joe" value="Joe">
i
の値が 23
の場合、asp-for="CollectionProperty[23].Member"
はコレクションのプロパティを使用して、asp-for="CollectionProperty[i].Member"
と同じ名前を生成します。
ASP.NET Core MVC で ModelExpression
の値が計算されるとき、ModelState
を含む、いくつかのソースが検査されます。 <input type="text" asp-for="Name">
を検討します。 計算された value
属性は、次のうちの最初の非 null 値です。
- キー "Name" を持つ
ModelState
エントリ。 - 式
Model.Name
の結果。
子プロパティの移動
ビュー モデルのプロパティ パスを使用して、子プロパティに移動することもできます。 子 Address
プロパティを含むより複雑なモデル クラスを考えてみましょう。
public class AddressViewModel
{
public string AddressLine1 { get; set; }
}
public class RegisterAddressViewModel
{
public string Email { get; set; }
[DataType(DataType.Password)]
public string Password { get; set; }
public AddressViewModel Address { get; set; }
}
このビューでは、Address.AddressLine1
にバインドしています。
@model RegisterAddressViewModel
<form asp-controller="Demo" asp-action="RegisterAddress" method="post">
<label>Email: <input asp-for="Email" /></label> <br />
<label>Password: <input asp-for="Password" /></label><br />
<label>Address: <input asp-for="Address.AddressLine1" /></label><br />
<button type="submit">Register</button>
</form>
Address.AddressLine1
に対して次の HTML が生成されます。
<input type="text" id="Address_AddressLine1" name="Address.AddressLine1" value="">
式の名前とコレクション
Colors
の配列を含むサンプル モデル:
public class Person
{
public List<string> Colors { get; set; }
public int Age { get; set; }
}
アクション メソッド:
public IActionResult Edit(int id, int colorIndex)
{
ViewData["Index"] = colorIndex;
return View(GetPerson(id));
}
次の Razor は、特定の Color
要素にアクセスする方法を示しています。
@model Person
@{
var index = (int)ViewData["index"];
}
<form asp-controller="ToDo" asp-action="Edit" method="post">
@Html.EditorFor(m => m.Colors[index])
<label asp-for="Age"></label>
<input asp-for="Age" /><br />
<button type="submit">Post</button>
</form>
Views/Shared/EditorTemplates/String.cshtml
テンプレート:
@model string
<label asp-for="@Model"></label>
<input asp-for="@Model" /> <br />
List<T>
を使用するサンプル:
public class ToDoItem
{
public string Name { get; set; }
public bool IsDone { get; set; }
}
次の Razor は、コレクションに対して反復処理を実行する方法を示しています。
@model List<ToDoItem>
<form asp-controller="ToDo" asp-action="Edit" method="post">
<table>
<tr> <th>Name</th> <th>Is Done</th> </tr>
@for (int i = 0; i < Model.Count; i++)
{
<tr>
@Html.EditorFor(model => model[i])
</tr>
}
</table>
<button type="submit">Save</button>
</form>
Views/Shared/EditorTemplates/ToDoItem.cshtml
テンプレート:
@model ToDoItem
<td>
<label asp-for="@Model.Name"></label>
@Html.DisplayFor(model => model.Name)
</td>
<td>
<input asp-for="@Model.IsDone" />
</td>
@*
This template replaces the following Razor which evaluates the indexer three times.
<td>
<label asp-for="@Model[i].Name"></label>
@Html.DisplayFor(model => model[i].Name)
</td>
<td>
<input asp-for="@Model[i].IsDone" />
</td>
*@
値を asp-for
または Html.DisplayFor
と同じコンテキストで使用する場合は、可能であれば foreach
を使用する必要があります。 一般に、反復子を割り当てる必要がないため、(使用可能なシナリオでは) for
の方が foreach
よりも優れています。ただし、LINQ 式内でのインデクサーの評価はコストが高くなる可能性があるため、最小限に抑える必要があります。
Note
上記のコメント付きサンプル コードは、ラムダ式を @
演算子に置き換えて、リスト内の各 ToDoItem
にアクセスする方法を示しています。
Textarea タグ ヘルパー
Textarea Tag Helper
タグ ヘルパーは、Input タグ ヘルパーと似ています。
<textarea> 要素のモデルから
id
属性とname
属性、データ検証属性を生成します。厳密な型指定を提供します。
HTML ヘルパーの代替:
Html.TextAreaFor
サンプル:
using System.ComponentModel.DataAnnotations;
namespace FormsTagHelper.ViewModels
{
public class DescriptionViewModel
{
[MinLength(5)]
[MaxLength(1024)]
public string Description { get; set; }
}
}
@model DescriptionViewModel
<form asp-controller="Demo" asp-action="RegisterTextArea" method="post">
<textarea asp-for="Description"></textarea>
<button type="submit">Test</button>
</form>
次の HTML が生成されます。
<form method="post" action="/Demo/RegisterTextArea">
<textarea data-val="true"
data-val-maxlength="The field Description must be a string or array type with a maximum length of '1024'."
data-val-maxlength-max="1024"
data-val-minlength="The field Description must be a string or array type with a minimum length of '5'."
data-val-minlength-min="5"
id="Description" name="Description">
</textarea>
<button type="submit">Test</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
ラベル タグ ヘルパー
式の名前の <label> 要素に対してラベルのキャプションと
for
属性を生成しますHTML ヘルパーの代替:
Html.LabelFor
。
Label Tag Helper
は、純粋な HTML の label 要素よりも次の点で優れています:
Display
属性からわかりやすいラベル値が自動的に取得されます。 意図した表示名は時間と共に変化する可能性があります。また、Display
属性とラベル タグ ヘルパーの組み合わせによって、使用されているあらゆる場所にDisplay
が適用されます。ソース コードのマークアップが少ない
モデルのプロパティを使用した厳密な型指定。
サンプル:
using System.ComponentModel.DataAnnotations;
namespace FormsTagHelper.ViewModels
{
public class SimpleViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email Address")]
public string Email { get; set; }
}
}
@model SimpleViewModel
<form asp-controller="Demo" asp-action="RegisterLabel" method="post">
<label asp-for="Email"></label>
<input asp-for="Email" /> <br />
</form>
<label>
要素に対して次の HTML が生成されます。
<label for="Email">Email Address</label>
ラベル タグ ヘルパーから "Email" の属性値 for
が生成されました。これは、<input>
に関連付けられた ID です。 タグ ヘルパーでは一貫性のある id
および for
要素が生成されるので、正しく関連付けられます。 このサンプルのキャプションは Display
属性に由来します。 モデルに Display
属性を含めなかった場合、キャプションは式のプロパティ名になります。 既定のキャプションをオーバーライドするには、ラベル タグ内にキャプションを追加します。
検証タグ ヘルパー
2 つの検証タグ ヘルパーがあります。 Validation Message Tag Helper
(モデルの単一のプロパティに関する検証メッセージを表示する) と Validation Summary Tag Helper
(検証エラーの概要を表示する) です。 Input Tag Helper
は、モデル クラスのデータ注釈属性に基づいて、HTML5 のクライアント側検証属性を input 要素に追加します。 検証はサーバー側でも実行されます。 検証エラーが発生すると、検証タグ ヘルパーによってこれらのエラー メッセージが表示されます。
検証メッセージ タグ ヘルパー
HTML5 の
data-valmsg-for="property"
属性を span 要素に追加します。これによって、指定されたモデル プロパティの入力フィールドに検証エラー メッセージがアタッチされます。 クライアント側の検証エラーが発生すると、jQuery によって<span>
要素のエラー メッセージが表示されます。検証はサーバー側でも実行されます。 クライアントで JavaScript が無効にされている場合や、一部の検証をサーバー側でのみ実行できる場合があります。
HTML ヘルパーの代替:
Html.ValidationMessageFor
Validation Message Tag Helper
は、HTML の span 要素で asp-validation-for
属性と共に使用されます。
<span asp-validation-for="Email"></span>
検証メッセージ タグ ヘルパーから、次の HTML が生成されます。
<span class="field-validation-valid"
data-valmsg-for="Email"
data-valmsg-replace="true"></span>
一般的に、同じプロパティの場合は、Input
タグ ヘルパーの後に Validation Message Tag Helper
を使用します。 こうすることで、エラーの原因となった入力の近くで検証エラー メッセージが表示されます。
Note
クライアント側の検証のために、正しい JavaScript および jQuery のスクリプト参照を使用したビューを用意する必要があります。 詳細については、モデルの検証に関するページを参照してください。
サーバー側の検証エラーが発生した場合 (カスタムのサーバー側の検証がある場合や、クライアント側の検証が無効な場合など)、MVC はそのエラー メッセージを <span>
要素の本文として配置します。
<span class="field-validation-error" data-valmsg-for="Email"
data-valmsg-replace="true">
The Email Address field is required.
</span>
検証概要タグ ヘルパー
asp-validation-summary
属性を持つ<div>
要素をターゲットとしますHTML ヘルパーの代替:
@Html.ValidationSummary
Validation Summary Tag Helper
は、検証メッセージの概要を表示するために使用されます。 asp-validation-summary
属性値には、次のいずれかを指定できます。
asp-validation-summary | 検証メッセージが表示されます |
---|---|
All |
プロパティとモデル レベル |
ModelOnly |
モデル |
None |
なし |
サンプル
次の例のデータ モデルは、DataAnnotation
属性が設定されており、<input>
要素に関する検証エラー メッセージを生成します。 検証エラーが発生すると、検証タグ ヘルパーはエラー メッセージを表示します。
using System.ComponentModel.DataAnnotations;
namespace FormsTagHelper.ViewModels
{
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email Address")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
}
}
@model RegisterViewModel
<form asp-controller="Demo" asp-action="RegisterValidation" method="post">
<div asp-validation-summary="ModelOnly"></div>
<label>Email: <input asp-for="Email" /></label> <br />
<span asp-validation-for="Email"></span><br />
<label>Password: <input asp-for="Password" /></label><br />
<span asp-validation-for="Password"></span><br />
<button type="submit">Register</button>
</form>
生成される HTML (モデルが有効な場合):
<form action="/DemoReg/Register" method="post">
<label>Email: <input name="Email" id="Email" type="email" value=""
data-val-required="The Email field is required."
data-val-email="The Email field is not a valid email address."
data-val="true"></label><br>
<span class="field-validation-valid" data-valmsg-replace="true"
data-valmsg-for="Email"></span><br>
<label>Password: <input name="Password" id="Password" type="password"
data-val-required="The Password field is required." data-val="true"></label><br>
<span class="field-validation-valid" data-valmsg-replace="true"
data-valmsg-for="Password"></span><br>
<button type="submit">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
選択タグ ヘルパー
HTML ヘルパーの代替の
Html.DropDownListFor
とHtml.ListBoxFor
があります
Select Tag Helper
asp-for
は select 要素のモデル プロパティ名を指定し、asp-items
は option 要素を指定します。 次に例を示します。
<select asp-for="Country" asp-items="Model.Countries"></select>
サンプル:
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;
namespace FormsTagHelper.ViewModels
{
public class CountryViewModel
{
public string Country { get; set; }
public List<SelectListItem> Countries { get; } = new List<SelectListItem>
{
new SelectListItem { Value = "MX", Text = "Mexico" },
new SelectListItem { Value = "CA", Text = "Canada" },
new SelectListItem { Value = "US", Text = "USA" },
};
}
}
Index
メソッドは CountryViewModel
を初期化し、選択された国を設定し、それを Index
ビューに渡します。
public IActionResult Index()
{
var model = new CountryViewModel();
model.Country = "CA";
return View(model);
}
HTTP POST Index
メソッドによって選択内容が表示されます。
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index(CountryViewModel model)
{
if (ModelState.IsValid)
{
var msg = model.Country + " selected";
return RedirectToAction("IndexSuccess", new { message = msg });
}
// If we got this far, something failed; redisplay form.
return View(model);
}
Index
ビュー:
@model CountryViewModel
<form asp-controller="Home" asp-action="Index" method="post">
<select asp-for="Country" asp-items="Model.Countries"></select>
<br /><button type="submit">Register</button>
</form>
次の HTML が生成されます ("CA" が選択されている場合)。
<form method="post" action="/">
<select id="Country" name="Country">
<option value="MX">Mexico</option>
<option selected="selected" value="CA">Canada</option>
<option value="US">USA</option>
</select>
<br /><button type="submit">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
Note
選択タグ ヘルパーで ViewBag
または ViewData
を使用することはお勧めしません。 ビュー モデルは、MVC メタデータを提供する場合に堅牢性が高くなり、一般的にあまり問題にはなりません。
asp-for
属性値は特殊なケースであり、(asp-items
などの) 他のタグ ヘルパー属性とは異なり、Model
プレフィックスは必須ではありません
<select asp-for="Country" asp-items="Model.Countries"></select>
Enum バインディング
<select>
を enum
プロパティと組み合わせて使用し、enum
値から SelectListItem
要素を生成すると便利な場合がよくあります。
サンプル:
public class CountryEnumViewModel
{
public CountryEnum EnumCountry { get; set; }
}
using System.ComponentModel.DataAnnotations;
namespace FormsTagHelper.ViewModels
{
public enum CountryEnum
{
[Display(Name = "United Mexican States")]
Mexico,
[Display(Name = "United States of America")]
USA,
Canada,
France,
Germany,
Spain
}
}
GetEnumSelectList
メソッドは列挙型の場合に SelectList
オブジェクトを生成します。
@model CountryEnumViewModel
<form asp-controller="Home" asp-action="IndexEnum" method="post">
<select asp-for="EnumCountry"
asp-items="Html.GetEnumSelectList<CountryEnum>()">
</select>
<br /><button type="submit">Register</button>
</form>
より高機能な UI にするために、列挙子リストを Display
属性でマークできます。
using System.ComponentModel.DataAnnotations;
namespace FormsTagHelper.ViewModels
{
public enum CountryEnum
{
[Display(Name = "United Mexican States")]
Mexico,
[Display(Name = "United States of America")]
USA,
Canada,
France,
Germany,
Spain
}
}
次の HTML が生成されます。
<form method="post" action="/Home/IndexEnum">
<select data-val="true" data-val-required="The EnumCountry field is required."
id="EnumCountry" name="EnumCountry">
<option value="0">United Mexican States</option>
<option value="1">United States of America</option>
<option value="2">Canada</option>
<option value="3">France</option>
<option value="4">Germany</option>
<option selected="selected" value="5">Spain</option>
</select>
<br /><button type="submit">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
オプション グループ
HTML の <optgroup> 要素は、ビュー モデルに 1 つ以上の SelectListGroup
オブジェクトが含まれている場合に生成されます。
CountryViewModelGroup
は SelectListItem
要素を "北米" グループと "ヨーロッパ" グループに分けます。
public class CountryViewModelGroup
{
public CountryViewModelGroup()
{
var NorthAmericaGroup = new SelectListGroup { Name = "North America" };
var EuropeGroup = new SelectListGroup { Name = "Europe" };
Countries = new List<SelectListItem>
{
new SelectListItem
{
Value = "MEX",
Text = "Mexico",
Group = NorthAmericaGroup
},
new SelectListItem
{
Value = "CAN",
Text = "Canada",
Group = NorthAmericaGroup
},
new SelectListItem
{
Value = "US",
Text = "USA",
Group = NorthAmericaGroup
},
new SelectListItem
{
Value = "FR",
Text = "France",
Group = EuropeGroup
},
new SelectListItem
{
Value = "ES",
Text = "Spain",
Group = EuropeGroup
},
new SelectListItem
{
Value = "DE",
Text = "Germany",
Group = EuropeGroup
}
};
}
public string Country { get; set; }
public List<SelectListItem> Countries { get; }
この 2 つのグループを次に示します。
生成される HTML:
<form method="post" action="/Home/IndexGroup">
<select id="Country" name="Country">
<optgroup label="North America">
<option value="MEX">Mexico</option>
<option value="CAN">Canada</option>
<option value="US">USA</option>
</optgroup>
<optgroup label="Europe">
<option value="FR">France</option>
<option value="ES">Spain</option>
<option value="DE">Germany</option>
</optgroup>
</select>
<br /><button type="submit">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
複数選択
asp-for
属性に指定されているプロパティが IEnumerable
の場合、Select タグ ヘルパーは multiple = "multiple" 属性を自動的に生成します。 たとえば、次のようなモデルがあるとします。
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;
namespace FormsTagHelper.ViewModels
{
public class CountryViewModelIEnumerable
{
public IEnumerable<string> CountryCodes { get; set; }
public List<SelectListItem> Countries { get; } = new List<SelectListItem>
{
new SelectListItem { Value = "MX", Text = "Mexico" },
new SelectListItem { Value = "CA", Text = "Canada" },
new SelectListItem { Value = "US", Text = "USA" },
new SelectListItem { Value = "FR", Text = "France" },
new SelectListItem { Value = "ES", Text = "Spain" },
new SelectListItem { Value = "DE", Text = "Germany"}
};
}
}
次のビューを対象にします。
@model CountryViewModelIEnumerable
<form asp-controller="Home" asp-action="IndexMultiSelect" method="post">
<select asp-for="CountryCodes" asp-items="Model.Countries"></select>
<br /><button type="submit">Register</button>
</form>
次の HTML が生成されます。
<form method="post" action="/Home/IndexMultiSelect">
<select id="CountryCodes"
multiple="multiple"
name="CountryCodes"><option value="MX">Mexico</option>
<option value="CA">Canada</option>
<option value="US">USA</option>
<option value="FR">France</option>
<option value="ES">Spain</option>
<option value="DE">Germany</option>
</select>
<br /><button type="submit">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
選択なし
複数のページで "未指定" オプションを使用しているとわかった場合は、テンプレートを作成して HTML の繰り返しを除去することができます。
@model CountryViewModel
<form asp-controller="Home" asp-action="IndexEmpty" method="post">
@Html.EditorForModel()
<br /><button type="submit">Register</button>
</form>
Views/Shared/EditorTemplates/CountryViewModel.cshtml
テンプレート:
@model CountryViewModel
<select asp-for="Country" asp-items="Model.Countries">
<option value="">--none--</option>
</select>
HTML の <option> 要素の追加は、"選択なし" の場合に限定されません。 たとえば、次のビューおよびアクション メソッドで、上記のコードのような HTML が生成されます。
public IActionResult IndexNone()
{
var model = new CountryViewModel();
model.Countries.Insert(0, new SelectListItem("<none>", ""));
return View(model);
}
@model CountryViewModel
<form asp-controller="Home" asp-action="IndexEmpty" method="post">
<select asp-for="Country">
<option value=""><none></option>
<option value="MX">Mexico</option>
<option value="CA">Canada</option>
<option value="US">USA</option>
</select>
<br /><button type="submit">Register</button>
</form>
現在の Country
値に応じて、(selected="selected"
属性を含む) 正しい <option>
要素が選択されます。
public IActionResult IndexOption(int id)
{
var model = new CountryViewModel();
model.Country = "CA";
return View(model);
}
<form method="post" action="/Home/IndexEmpty">
<select id="Country" name="Country">
<option value=""><none></option>
<option value="MX">Mexico</option>
<option value="CA" selected="selected">Canada</option>
<option value="US">USA</option>
</select>
<br /><button type="submit">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>">
</form>
その他のリソース
ASP.NET Core