ValidationSummary 未在 messagestore.add 上更新

ValidationSummary not updating on messagestore.add

我通过 api 检查了远程登录并将验证错误添加到 ValidationMessageStore,但它们没有出现在 ValidationSummary 中。我想在另一个复杂的场景中使用相同的过程,我在其中更改迁移前端。

如果我更改输入并出现“正常”错误,如出现必填消息,所有错误都会出现在摘要中。必需的错误和我的凭据错误。我认为唯一的问题是:未检查验证摘要,里面有一条新的错误消息。但是我不知道,我怎么戳ValidationSummary

这里是 LogIn.razor.

<EditForm OnValidSubmit="ExecuteLogin" class="card card-body bg-light mt-5" EditContext="editContext">
    <p>DataAnnotationsValidator</p>
    <DataAnnotationsValidator />
    <p>ValidationSummary</p>
    <ValidationSummary />

    <div class="form-group row">
        <label for="email" class="col-md-2 col-form-label">Email:</label>
        <div class="col-md-10">
            <InputText id="email" class="form-control" @bind-Value="model.Email" />
            <ValidationMessage For="@(() => model.Email)" />
        </div>
    </div>

    <div class="form-group row">
        <label for="password" class="col-md-2 col-form-label">Password:</label>
        <div class="col-md-10">
            <InputText type="password" id="password" class="form-control" @bind-Value="model.Password" />
            <ValidationMessage For="@(() => model.Password)" />
        </div>
    </div>

    <div class="row justify-content-md-center">
        <div class="col-md-3">
            <button type="submit" class="btn btn-success">Log In</button>
        </div>
    </div>
</EditForm>

这里是 Login.razor.cs

  public partial class LogIn
    {

        private EditContext? editContext;
        private ValidationMessageStore? _messageStore;

        private AuthenticationUserRequest model = new();

        protected override void OnInitialized()
        {
            editContext = new(model);
            editContext.OnValidationRequested += OnValidationRequested;
            _messageStore = new(editContext);
        }

        public void Dispose()
        {
            editContext.OnValidationRequested -= OnValidationRequested;
        }

        protected override async Task OnInitializedAsync()
        {
            var state = await _stateProvider.GetAuthenticationStateAsync();
            if (state.User.Identity.IsAuthenticated)
            {
                _navigationManager.NavigateTo("/");
            }
        }


        private void OnValidationRequested(object? sender, ValidationRequestedEventArgs e)
        {
            _messageStore?.Clear();
        }


        private async Task ExecuteLogin()
        {

            var result = await _authenticationManager.Login(model);
            if (result.Succeeded)
            {
                // Notify User and navigate to home
            }
            else
            {
                
                foreach (var message in result.Messages)
                {
                    if (message == "Invalid Credentials.")
                    {
                        _messageStore.Add(() => model.Email, "Invalid Credentials");
                        _messageStore.Add(() => model.Password, "Invalid Credentials");
                        _messageStore.Add(() => model.Password, "Another Error for testing");
                        StateHasChanged();

                    }
                    else
                    {
                        // Notify User
                    }
                }
            }
        }
    }

我已经稍微简化了您的代码以创建单个组件。你看下面的代码。

回答您的问题“将验证错误添加到 ValidationMessageStore,但它们不会出现在 ValidationSummary 中”。

他们不这样做,因为 ValidationSummaryValidationMessage 的行为略有不同。

这些是使事情发生的重要变化:

  1. 我已经删除了你的 ValidationStateChanged 注册,因为我认为你不需要它。
  2. 我添加了在添加自定义消息之前清除消息存储ExecuteLogIn
  3. 添加消息后调用 editContext!.NotifyValidationStateChanged();

第 3 步是 ValidationSummary 的重要部分。随着 ExecuteLogIn 的产生,EditContext 获得线程时间到 运行 OnValidationStateChanged 注册的事件处理程序。 ValidationSummary 就是其中之一。它会在您添加自定义消息之前读取“空”验证存储并重新呈现。当您最终重新呈现主页时,ValidationSummary 没有任何变化,因此没有最终重新呈现。调用 NotifyValidationStateChanged 触发重新渲染。

using Microsoft.AspNetCore.Components.Forms;

namespace Whosebug.Server.Pages
{
    public partial class LogIn
    {
        private EditContext? editContext;
        private ValidationMessageStore? _messageStore;

        private AuthenticationUserRequest model = new();

        protected override Task OnInitializedAsync()
        {
            editContext = new(model);
            _messageStore = new(editContext);
            return Task.CompletedTask;
        }

        private async Task ExecuteLogin()
        {
            var result =  await this.ValidateLogin();
            if (result)
            {
                // Notify User and navigate to home
            }
            else
            {
                _messageStore?.Clear();
                _messageStore!.Add(() => model.Email, "Invalid Email");
                _messageStore!.Add(() => model.Password, "Invalid Password");
                _messageStore!.Add(() => model.Message, "Invalid Credentials");
                editContext!.NotifyValidationStateChanged();
                await this.InvokeAsync(StateHasChanged);
            }
        }

        private async Task<bool> ValidateLogin()
        {
             await Task.Delay(1000);
            return false;
        }
    }

    public class AuthenticationUserRequest
    {
        public string Email { get; set; } = String.Empty;
        public string Password { get; set; } = String.Empty;
        public string Message { get; set; } = string.Empty;
    }

}