👌

BlazorのValidationSummaryでasp-validation-summaryのように表示エラーメッセージを絞り込みたい

2023/01/29に公開

ASP.NET Core Blazor のバリデーションのエラーメッセージを表示する際にプロパティのエラーは各コントロールの横に表示して、モデル全体にかかわるエラーに関してはフォームの上のほうに、リスト形式で出したいというケースがあると思います。

以下のような感じですね。


プロパティに紐づくエラーは、入力項目のすぐそばに表示


オブジェクト全体に紐づくエラーはフォームの上に表示

ただ、以下のように普通に ValidationSummary コンポーネントを置くとプロパティに紐づくエラーもオブジェクトに紐づくエラーもどちらも表示されてしまいます。

<EditForm Model="_model" OnValidSubmit="OnValidSubmit" OnInvalidSubmit="OnInvalidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <fieldset>
        <legend>Name</legend>
        <div>
            <label>First name</label>
            <InputText @bind-Value="_model.FirstName" />
            <ValidationMessage For="() => _model.FirstName" />
        </div>
        
        <div>
            <label>Last name</label>
            <InputText @bind-Value="_model.LastName" />
            <ValidationMessage For="() => _model.LastName" />
        </div>
    </fieldset>

    <button type="submit">Submit</button>
</EditForm>


プロパティのエラーも出ちゃう…

オブジェクトに紐づくエラーだけにする方法

ということで解決策です。ValidationSummary コンポーネントには Model プロパティがあって、これを設定することでオブジェクトに紐づくエラーだけ表示されるようになります。以下のような感じです。

<ValidationSummary Model="_model" />

まとめ

ということで ValidatoinSummaryModel プロパティの紹介でした。

コード全体

入力値を保持するためのクラス

Person.cs
using System.ComponentModel.DataAnnotations;

namespace EmptyBlazorApp2.Models;

class Person : IValidatableObject
{
    [Required]
    public string? FirstName { get; set; }

    [Required]
    public string? LastName { get; set; }

    public string? FullName => (FirstName, LastName) switch
    {
        (null, null) => null,
        (null, string lastName) => lastName,
        (string firstName, null) => firstName,
        (string firstName, string lastName) => $"{firstName} {lastName}",
    };

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (FirstName == LastName)
        {
            yield return new ValidationResult("FirstName と LastName に同じ値は入れたらだめ。");
        }
    }
}
Index.razor
@page "/"
@using System.ComponentModel.DataAnnotations;
@using EmptyBlazorApp2.Models;

<EditForm Model="_model" OnValidSubmit="OnValidSubmit" OnInvalidSubmit="OnInvalidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary Model="_model" />
    <fieldset>
        <legend>Name</legend>
        <div>
            <label>First name</label>
            <InputText @bind-Value="_model.FirstName" />
            <ValidationMessage For="() => _model.FirstName" />
        </div>
        
        <div>
            <label>Last name</label>
            <InputText @bind-Value="_model.LastName" />
            <ValidationMessage For="() => _model.LastName" />
        </div>
    </fieldset>

    <button type="submit">Submit</button>
</EditForm>

<p>@_message</p>

@code {
    private Person _model = new();

    private string _message = "";

    private void OnValidSubmit(EditContext editContext)
    {
        _message = $"Valid: {_model.FullName}";
    }

    private void OnInvalidSubmit(EditContext editContext)
    {
        _message = $"Invalid: {_model.FullName}";

    }
}
Microsoft (有志)

Discussion