0
0

Ant Design Blazorでカスタム検証を使用してみる

Posted at

BlazorWebAssemblyでAnt Design Blazorを触っています。
Ant Design Blazorは、コンポーネントの数が多く、ドキュメントの内容が濃いので、
お気に入りのUIフレームワークです。見た目もおしゃれで、胸熱です。

既にカスタム検証が実装済の状態で、Ant Design Blazorでどうやって適応させるのかつまずいてしまったので、現段階の解決策を書いてみようと思います。

他にいい方法があれば、コメントで教えてください:bow:

バージョンなど

  • .NET 8.0.204
  • Microsoft.AspNetCore.Components.WebAssembly 8.0.4
  • AntDesign 0.18.3

カスタム検証の内容

1.カスタム検証

CustomValidation.cs
public class RequiredCustomValidation : ValidationAttribute
{
    protected override ValidationResult IsValid(object? value, ValidationContext context)
    {
        if(value is null || string.IsNullOrEmpty(value.ToString()))
        {
            var propertyName = ReflectionHelper.GetPropertyName(context);
            return new ValidationResult($"{propertyName}は必須項目です", new[] { propertyName });
        }

        return ValidationResult.Success!;
    }
}

2. プロパティ名取得

ReflectionHelper.cs
public static class ReflectionHelper
{
    public static string GetPropertyName(ValidationContext context)
    {
        var member = context.ObjectInstance as MemberExpression;
        if (member is null)
        {
            return context.DisplayName;
        }

        var property = member.Member as PropertyInfo;
        if (property is null)
        {
            return context.DisplayName;
        }

        return property.Name;
    }
}

画面の実装

FormComponent.razor
@page "/form"

<Card>
	<Body>
		<Form Model="UserVM" TModel="User" LabelColSpan="4" WrapperColSpan="16">
			<FormItem>
				<Input @bind-Value="UserVM.Email"></Input>
			</FormItem>
			<FormItem>
				<Input @bind-Value="UserVM.Password"></Input>
			</FormItem>
			<FormItem WrapperColOffset="4" WrapperColSpan="16">
				<Button Type="@ButtonType.Primary">Submit</Button>
			</FormItem>
		</Form>
	</Body>
</Card>
FormComponent.razor.cs
public partial class FormComponent
{
    private User UserVM { get; set; } = new();

    public class User
    {
        [DisplayName("メールアドレス")]
        public string Email { get; set; }

        [DisplayName("パスワード")]
        public string Password { get; set; }
    }
}

実装

Ant Design Blazorの導入については、公式ドキュメントに記載があるので割愛します。

1.カスタム検証をAnt Design Blazorで使用できるように修正

IsValidFormatErrorMessageをAnt Design Blazorで使用できるように関数を分割化しました。
通常の場合は、IsValid(object? value, ValidationContext context)が呼ばれる想定です。

CustomValidation.cs
public class RequiredCustomValidation : ValidationAttribute
{
    protected override ValidationResult IsValid(object? value, ValidationContext context)
    {
        if(IsValid(value))
        {
            var propertyName = ReflectionHelper.GetPropertyName(context);
            return new ValidationResult(FormatErrorMessage(propertyName));
        }

        return ValidationResult.Success!;
    }

    public override bool IsValid(object? value)
    {
        return value is null || string.IsNullOrEmpty(value.ToString());
    }

    public override string FormatErrorMessage(string name)
    {
        return string.Format("{0}は必須項目です", name);
    }
}

2.ValidtionRulesの実装

Ant Design Blazorの場合は、プロパティに属性として追加するのではなく、
ルールを定義し、定義したルールをformItemに設定することでValidationの設定ができます。

メールアドレスの検証ルールをRequiredCustomValidationを呼び出して設定することで、
検証ルールの共通化が図れます。

FormComponent.razor.cs
    private FormValidationRule[] emailRules = new FormValidationRule[]{
    new FormValidationRule { Validator = (validationContext) => {
            var validationAttribute = new RequiredCustomValidation();

            if (validationAttribute.IsValid(validationContext.Value))
            {
                string errorMessage = validationAttribute.FormatErrorMessage(validationContext.DisplayName);

                var result = new ValidationResult(errorMessage, new string[] { validationContext.FieldName });

                return result;
            }

            return null;
        }
    },
};

formにValidateMode="@FormValidateMode.Rules"を設定することで、
検証ルールでvalidationを行うことを設定できます。
formItemに先ほど作成したemailRulesを設定し、準備は完了です。

FormComponent.razor
@page "/form"

<Card>
	<Body>
		<Form Model="UserVM" TModel="User" LabelColSpan="4" WrapperColSpan="16" ValidateMode="@FormValidateMode.Rules">
			<FormItem Rules="@(emailRules)">
				<Input @bind-Value="UserVM.Email"></Input>
			</FormItem>
			<FormItem>
				<Input @bind-Value="UserVM.Password"></Input>
			</FormItem>
			<FormItem WrapperColOffset="4" WrapperColSpan="16">
				<Button Type="@ButtonType.Primary" HtmlType="submit">Submit</Button>
			</FormItem>
		</Form>
	</Body>
</Card>

結果

下記のように、submitボタンクリック時に検証が走り、
検証ルールに設定した検証が実行されていることを確認しました。
スクリーンショット 2024-05-06 192419.png

補足

formにValidateMode="@FormValidateMode.Rules"と設定すると、Attribute属性にRequiredを設定していても、必須マークが設定されなくなってしまいます。
そのため、formItemにRequiredの設定をして必須マークを付与してください。

FormComponent.razor
<FormItem Rules="@(emailRules)" Required>
	<Input @bind-Value="UserVM.Email"></Input>
</FormItem>

最後に

フロントエンドとサーバーサイドで検証ルールを共通化できるよう、
UIフレームワークでも検証ルールの設定方法を考えてみました。

やっていることは、とても単純なのですが、
一度沼にはまると、なかなか思いつかなかったので、
今後のためにも記録していきたいと思います。

まだまだ初心者のため、その他最善策などありましたらコメントお願いします!

参考にしたリンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0