I checked the login remote by a api and adding the validation-errors to ValidationMessageStore
, but they don't appers in ValidationSummary
. I want to use the same process in another complex szenarios, where i change migrate the frontend.
If i change the input and a "normal" error comes up, like a required-message appear, all errors appear in the summary. The required-Error and my credential errors. I think the only problem is: that the validation summary don't checked, that there is a new error Message inside. But i don' t know, how i can poke the ValidationSummary
.
Here is the 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>
And here the 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
}
}
}
}
}
I've simplified your code a little to create a single component. You see the code below.
To answer your question "adding the validation-errors to ValidationMessageStore, but they don't appers in ValidationSummary".
THEY DON'T, because of the slightly different behaviour of the ValidationSummary
and ValidationMessage
.
These are the important changes to make things happen:
ValidationStateChanged
registration as I don't think you need it.ExecuteLogIn
before adding the custom messageseditContext!.NotifyValidationStateChanged();
after adding the messages.Step 3 is the important bit for ValidationSummary
. As ExecuteLogIn
yields, EditContext
get thread time to run the OnValidationStateChanged
registered event handlers. ValidationSummary
is one of these. It reads the "empty" validation store and re-renders long before you have added the custom messages. Nothing has changed for ValidationSummary
when you finally re-render your main page, so no final re-render. Calling NotifyValidationStateChanged
triggers that re-render.
using Microsoft.AspNetCore.Components.Forms;
namespace StackOverflow.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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With