Razor Pagesのフォームの入力内容を独自の処理で検証するコードを紹介します。
こちらの記事ではRazor Pagesのシンプルな入力内容の検証を実装しました。
この記事では、入力された内容を独自のロジックで検証するプログラムのコードを紹介します。
入力内容が送信される際に、IsValid メソッドが呼び出されます。
IsValidメソッドをオーバーライドし独自の検証ロジックを実装します。検証に成功した場合は、ValidationResult.Success を返し、失敗した場合は、
エラーメッセージを含めた ValidationResult 負ぶえジェクトを返します。
ASP.NET Core アプリケーションを作成し、以下のファイル、コードを記述します。
@page
@model RazorPagesValidation.Pages.CustomValidation01Model
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
<head></head>
<body>
<h2>入力内容のカスタム検証のデモ</h2>
<form method="post">
<input type="text" asp-for="inputText"/>
<input type="submit" value="Exec" />
</form>
<p>@Model.MessageText</p>
</body>
</html>
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace RazorPagesValidation.Pages
{
public class MyValueAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string svalue = (string)value;
if (svalue == "Penguin" || svalue == "Duck")
{
return ValidationResult.Success;
}
else
{
return new ValidationResult("Invalid Value");
}
}
}
public class CustomValidation01Model : PageModel
{
[BindProperty]
[MyValueAttribute]
public string inputText { get; set; }
public string MessageText { get; set; }
public void OnGet()
{
}
public PageResult OnPost()
{
if (ModelState.IsValid == true)
{
MessageText = "処理は成功しました。";
return Page();
}
else
{
foreach (ModelStateEntry se in ModelState.Values)
{
foreach (ModelError me in se.Errors)
{
MessageText += me.ErrorMessage;
}
}
return Page();
}
}
}
}
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
app.MapRazorPages();
app.Run();
カスタムの検証ロジックを実装する場合、検証処理を実装する ValidationAttribute
クラスを継承したカスタムの継承クラスを作成します。
今回は MyValueAttribute クラスとしています。
IsValid
メソッドをオーバーライドし、検証する処理をメソッド内に実装します。
検証が正しかった場合は、ValidationResult.Success
を返し、
誤っていた場合は、ValidationResult
オブジェクトを返します。ValidationResult オブジェクトのコンストラクタの第一引数に、エラーとなるメッセージを与えます。
フィールド(テキストボックス等)に入力された値は、IsValidの第一引数のvalue
変数に設定されます。
今回の例では、テキストボックスの入力文字列が、"Penguin" "Duck" の場合は問題なしとし、
それ以外の値が入力された場合は、無効な値としてエラーを返す実装としています。
public class MyValueAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string svalue = (string)value;
if (svalue == "Penguin" || svalue == "Duck")
{
return ValidationResult.Success;
}
else
{
return new ValidationResult("Invalid Value");
}
}
}
検証ロジックを適用する入力プロパティには [(ValidationAttributeを継承したカスタム検証クラス)]
の属性を記述します。
今回の例では、ValidationAttributeクラスを継承した、MyValueAttribute クラスを属性に記述します。
[BindProperty]
[MyValueAttribute]
public string inputText { get; set; }
検証ロジックを実行する部分です。通常は、OnPostメソッドでフォームの内容が送信された際にModelState.IsValid
プロパティの値を確認します。
true
であれば検証は成功し、処理を続行します。false
の場合は検証に失敗したことになるため、エラーメッセージを表示します。
エラーメッセージは、ModelState.Values
プロパティの Errors
プロパティにメッセージが設定されています。複数のエラーメッセージが
設定されている場合もあるため、Errors
プロパティの値をループ等で取得しページに出力します。
public PageResult OnPost()
{
if (ModelState.IsValid == true)
{
MessageText = "処理は成功しました。";
return Page();
}
else
{
foreach (ModelStateEntry se in ModelState.Values)
{
foreach (ModelError me in se.Errors)
{
MessageText += me.ErrorMessage;
}
}
return Page();
}
}
プロジェクトを実行し、(アプリケーションルートURL)/CustomValidation01
にアクセスします。下図のウィンドウが表示されます。
テキストボックスに Bear
を入力します。
[Exec]ボタンをクリックします。入力値が"Penguin" "Duck"以外なので、検証に失敗し "Invalid Value" のメッセージが表示されます。
続いて、テキストボックスに "Penguin" を入力します。入力後[Exec]ボタンをクリックします。
クリックすると、検証が成功し "処理は成功しました。" のメッセージが表示されます。
テキストボックスに "Duck" を入力した場合も同様に成功します。
ASP.NET Coreアプリケーションを作成します。
以下のコードを記述します。
@page
@model RazorPagesValidation.Pages.CustomValidation02Model
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
}
<html>
<head></head>
<body>
<h2>入力内容のカスタム検証のデモ</h2>
<form method="post">
<input type="text" asp-for="inputText1"/><br />
<text>@Model.ErrorMessageText1</text><br/>
<input type="text" asp-for="inputText2"/><br />
<text>@Model.ErrorMessageText2</text><br/>
<input type="text" asp-for="inputText3"/><br />
<text>@Model.ErrorMessageText3</text><br/>
<input type="submit" value="Exec" />
</form>
<p>@Model.MessageText</p>
</body>
</html>
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace RazorPagesValidation.Pages
{
public class MyValue1Attribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string svalue = (string)value;
if (svalue == "Penguin" || svalue == "Duck") {
return ValidationResult.Success;
}
else {
return new ValidationResult("Penguin か Duck のどちらかを入力してください。");
}
}
}
public class MyValue2Attribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
int ivalue;
if (int.TryParse((string)value, out ivalue) == true) {
return ValidationResult.Success;
}
else {
return new ValidationResult("数値を入力してください。");
}
}
}
public class MyValue3Attribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string svalue = (string)value;
System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex("^[A-Z]$");
System.Text.RegularExpressions.Match match = reg.Match(svalue);
if (match.Success == true) {
return ValidationResult.Success;
}
else {
return new ValidationResult("AからZの大文字一文字を入力してください。");
}
}
}
public class CustomValidation02Model : PageModel
{
[BindProperty]
[MyValue1Attribute]
public string inputText1 { get; set; }
[BindProperty]
[MyValue2Attribute]
public string inputText2 { get; set; }
[BindProperty]
[MyValue3Attribute]
public string inputText3 { get; set; }
public string ErrorMessageText1 { get; set; }
public string ErrorMessageText2 { get; set; }
public string ErrorMessageText3 { get; set; }
public string MessageText { get; set; }
public void OnGet()
{
}
public PageResult OnPost()
{
if (ModelState.IsValid == true) {
MessageText = "処理は成功しました。";
}
else {
ErrorMessageText1 = "";
if (ViewData.ModelState["inputText1"] != null) {
ModelStateEntry mse = ViewData.ModelState["inputText1"]!;
foreach (ModelError me in mse.Errors) {
ErrorMessageText1 += me.ErrorMessage;
}
}
if (ViewData.ModelState["inputText2"] != null) {
ModelStateEntry mse = ViewData.ModelState["inputText2"]!;
ErrorMessageText2 = "";
foreach (ModelError me in mse.Errors) {
ErrorMessageText2 += me.ErrorMessage;
}
}
if (ViewData.ModelState["inputText3"] != null) {
ModelStateEntry mse = ViewData.ModelState["inputText3"]!;
ErrorMessageText3 = "";
foreach (ModelError me in mse.Errors) {
ErrorMessageText3 += me.ErrorMessage;
}
}
}
return Page();
}
}
}
複数の入力プロパティがあり、それぞれの検証ロジックが違う場合、別々のValidationAttributeから派生した検証クラスを割り当てます。
[BindProperty]
[MyValue1Attribute]
public string inputText1 { get; set; }
[BindProperty]
[MyValue2Attribute]
public string inputText2 { get; set; }
[BindProperty]
[MyValue3Attribute]
public string inputText3 { get; set; }
検証ロジックのクラスです。MyValue1Attribute は入力文字列が "Penguin" か "Duck" のどちらかの入力でないとエラーとします。
MyValue2Attribute は入力値が数値でないとエラーとします。MyValue3Attribute はAからZの大文字1文字でないとエラーとします。
public class MyValue1Attribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string svalue = (string)value;
if (svalue == "Penguin" || svalue == "Duck") {
return ValidationResult.Success;
}
else {
return new ValidationResult("Penguin か Duck のどちらかを入力してください。");
}
}
}
public class MyValue2Attribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
int ivalue;
if (int.TryParse((string)value, out ivalue) == true) {
return ValidationResult.Success;
}
else {
return new ValidationResult("数値を入力してください。");
}
}
}
public class MyValue3Attribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string svalue = (string)value;
System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex("^[A-Z]$");
System.Text.RegularExpressions.Match match = reg.Match(svalue);
if (match.Success == true) {
return ValidationResult.Success;
}
else {
return new ValidationResult("AからZの大文字一文字を入力してください。");
}
}
プロジェクトを実行します。(アプリケーションルートURL)/CustomValidation02
のURLにアクセスします。
下図のページが表示されます。
上のテキストボックスから順に "a" "b" "c" を入力します。
[Exec]ボタンをクリックします。すべて不適の入力になるため、バリデーションエラーのメッセージがテキストボックスの下部に表示されます。
続いて、テキストボックスで上から順に "Penguin" "200" "G" を入力し、[Exec]ボタンをクリックします。
すべての検証が通り、"処理は成功しました。"のメッセージが表示されます。
テキストボックスに "Penguin" "AAB" "G" を入力し、[Exec]ボタンをクリックします。
2番目のテキストボックスの検証に失敗し、2番目のテキストボックスの下部にのみバリデーションエラーのメッセージが表示されます。
テキストボックスに "Camel" "AAB" "G" を入力し、[Exec]ボタンをクリックします。
1番目と2番目のテキストボックスの検証に失敗し、2つのテキストボックスの下部にバリデーションエラーのメッセージが表示されます。
Razor Pagesで入力フォームの検証処理が実装できました。