🐦

ASP.NET Razor Pages を最初から(9)

2023/02/17に公開

はじめに

Webアプリケーションで最もよく使われる機能の一つと思われる、Webフォームを作成する機能について見ていく。
その後に、頻繁に使いそうなフォームの作成を支援するタグヘルパーの使い方を簡単に確認する。

簡単なフォームサンプルと流れ

フォーム用に新しくCreate.cshtmlCreate.cshtml.csを作成して、CreateModelにフォーム用のプロパティ、NameEmailを作成する。

Create.cshtml.cs
public class CreateModel : PageModel
{
    [BindProperty]
    public string Name { get; set; }
    [BindProperty]
    public string Email { get; set; }

    public void OnGet()
    {
    }
}

送信するためのフォームを、Create.cshtmlに作成する。

Create.cshtml
@page
@model ZennSample.Pages.CreateModel
<form method="post">
    <div class="form-group">
        <label asp-for="Name"></label> <!-- Nameプロパティに名前を合わせる -->
        <input asp-for="Name" class="form-control" />
        <span asp-validation-for="Name" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Email"></label> <!-- Emailプロパティに名前を合わせる -->
        <input asp-for="Email" class="form-control" />
        <span asp-validation-for="Email" class="text-danger"></span>
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

POSTメソッドで送信するので、CreateModelにPOSTリクエストを受け付けるためのOnPostメソッドを追加する。

Create.cshtml.cs
public IActionResult OnPost()
{
    // 送信されたデータを検証
    if (!ModelState.IsValid)
    {
        // 検証失敗の場合ページを再表示
        return Page();
    }
    // 成功したらリダイレクトする(とりあえずトップページに)
    return RedirectToPage("./Index");
}

実行。
Create.cshtml
NameEmailを入力するフォームが現れるので、まずは何も入力せずSubmitする。

Create.cshtml Error
何も設定していないが画面にrequiredとエラーが表示された。
プロパティに[Required]属性は付けていないが、おそらくプロパティの型がNULLを許容しないstringだからだろう。

次は適当な値を入れてSubmitする。

検証を通過して、トップページにリダイレクトする事が確認できた。

Razorでのフォーム作成は、フォームとそれに対応するプロパティ(モデル)を作成して、OnPostメソッドでIsValidする流れを基本的な流れとして覚えておく。

送信データを検証する

検証用フォーム作成

先ほど作成したCreateModelに、AgeプロパティとCountryプロパティを追加する。
AgeintCountrystringにする。
Countryはセレクトボックスで入力できるようにする。

Create.cshtml.csCreate.shtmlにコードを追加する。

Create.cshtml.cs
[BindProperty]
public int Age { get; set; }
[BindProperty]
public string Country { get; set; }

// セレクトボックスの選択肢用のプロパティ
public List<SelectListItem> Countries { get; } = new List<SelectListItem>
{
	new SelectListItem { Value = "JP", Text = "Japan" },
	new SelectListItem { Value = "MX", Text = "Mexico" },
	new SelectListItem { Value = "CA", Text = "Canada" },
	new SelectListItem { Value = "US", Text = "USA"  },
};

セレクトボックスの各項目はSelectListItemが使われる。
プロパティは、SelectListItemListを作成しておく。
プロパティの宣言と同時に初期化してしまうのでgetのみ指定しておく。

Create.cshtml
<div class="form-group">
	<label asp-for="Age"></label>
	<input asp-for="Age" class="form-control" />
	<span asp-validation-for="Age" class="text-danger"></span>
</div>

<div class="form-group">
	<label asp-for="Country"></label>
	<select asp-for="Country" asp-items="Model.Countries" class="form-control"></select>
	<span asp-validation-for="Country" class="text-danger"></span>
</div>

AgeNameEmailと同様だが、Countryはセレクトボックスにするので、<select></select>タグを使用する。
asp-for="Country"は同様だが、リスト項目はap-itemsCountriesプロパティを設定する。
asp-forとの違いとして、asp-forModel.Nameのように書く必要がないが、asp-itemsasp-items="Model.Countries"とちゃんとModelと書く必要がある(無いとエラーになる)。

実行すると、セレクトボックスには選択肢が表示され、Ageのところは数字入力になっている。

検証属性を付与する

フォーム部分が完成したので検証属性を各プロパティに付与していく。
よく使いそうなものとしては

属性 用途
Required 入力必須
StringLength 文字列の長さ
Range 数字の範囲
DataType 日付
RegularExpression 正規表現
EmailAddress メールアドレス

こんなもんだろうか。
各プロパティに適当に付与してみる。

Create.cshtml.cs
[BindProperty]
[Required]
[StringLength(maximumLength:10,MinimumLength =5, ErrorMessage = "5文字以上10文字以内")]
public string Name { get; set; }

[BindProperty]
[Required]
[EmailAddress]
public string Email { get; set; }

[BindProperty]
[Required]
[Range(18,99, ErrorMessage = "18以上、99以下")]
public int Age { get; set; }

[Required]
[BindProperty]
public string Country { get; set; }


ちゃんと検証ができている事が確認できた。

時間がなかったので雑になってしまった、いつか書き直そうと思う。
しばらくはHack The Boxに取り組む。

Discussion