I am using Blazor Server, Fluent Validation and Blazored.FluentValidation. I have not really used Fluent Validation for front end for a very long time but I remember when I was using Jquery Validate + Fluent Validation once you tabbed out of say a textbox the basic validations would fire.
So if the field was required, and you left that textbox it would say right away it was required. If you tried to use a more complex control then the validation may not fire until you did a submit.
I can't even get the basic validation to fire immediately and wondering how it can be done.
Even if I use the sample code that comes with Blazored.FluentValidation
public class Person
{
public string? FirstName { get; set; }
public string? LastName { get; set; }
public int? Age { get; set; }
public string? EmailAddress { get; set; }
public Address Address { get; set; } = new();
}
public class PersonValidator : AbstractValidator<Person>
{
public PersonValidator()
{
RuleSet("Names", () =>
{
RuleFor(p => p.FirstName)
.NotEmpty().WithMessage("You must enter your first name")
.MaximumLength(50).WithMessage("First name cannot be longer than 50 characters");
RuleFor(p => p.LastName)
.NotEmpty().WithMessage("You must enter your last name")
.MaximumLength(50).WithMessage("Last name cannot be longer than 50 characters");
});
RuleFor(p => p.Age)
.NotNull().WithMessage("You must enter your age")
.GreaterThanOrEqualTo(0).WithMessage("Age must be greater than 0")
.LessThan(150).WithMessage("Age cannot be greater than 150");
RuleFor(p => p.EmailAddress)
.NotEmpty().WithMessage("You must enter an email address")
.EmailAddress().WithMessage("You must provide a valid email address")
.MustAsync(async (email, _) => await IsUniqueAsync(email)).WithMessage("Email address must be unique");
RuleFor(p => p.Address).SetValidator(new AddressValidator());
}
private static async Task<bool> IsUniqueAsync(string? email)
{
await Task.Delay(300);
return email?.ToLower() != "[email protected]";
}
}
<EditForm Model="@_person" OnValidSubmit="@SubmitValidForm">
<FluentValidationValidator @ref="_fluentValidationValidator" DisableAssemblyScanning="@true" />
<ValidationSummary />
<p>
<label>First Name: </label>
<InputText @bind-Value="@_person.FirstName" />
<ValidationMessage For="@(() => _person.FirstName)" />
</p>
<p>
<label>Last Name: </label>
<InputText @bind-Value="@_person.LastName" />
<ValidationMessage For="@(() => _person.LastName)" />
</p>
<hr />
<p>
<label>Age: </label>
<InputNumber @bind-Value="@_person.Age" />
<ValidationMessage For="@(() => _person.Age)" />
</p>
<p>
<label>Email Address: </label>
<InputText @bind-Value="@_person.EmailAddress" />
<ValidationMessage For="@(() => _person.EmailAddress)" />
</p>
<p>
<label>Address: Line 1: </label>
<InputText @bind-Value="@_person.Address.Line1" />
<ValidationMessage For="@(() => _person.Address.Line1)" />
</p>
<p>
<label>Address: Line 2: </label>
<InputText @bind-Value="@_person.Address.Line2" />
</p>
<p>
<label>Address: Town: </label>
<InputText @bind-Value="@_person.Address.Town" />
<ValidationMessage For="@(() => _person.Address.Town)" />
</p>
<p>
<label>Address: County: </label>
<InputText @bind-Value="@_person.Address.County" />
<ValidationMessage For="@(() => _person.Address.County)" />
</p>
<p>
<label>Address: Postcode: </label>
<InputText @bind-Value="@_person.Address.Postcode" />
<ValidationMessage For="@(() => _person.Address.Postcode)" />
</p>
<button type="submit">Save</button>
</EditForm>
<br />
<button @onclick="PartialValidate">Partial Validation</button>
@code {
private readonly Person _person = new();
private FluentValidationValidator? _fluentValidationValidator;
private void SubmitValidForm()
=> Console.WriteLine("Form Submitted Successfully!");
private void PartialValidate()
=> Console.WriteLine($"Partial validation result : {_fluentValidationValidator?.Validate(options => options.IncludeRuleSets("Names"))}");
}
I only see the validation if I use the submit buttons or if I go into say the "age" box and type an age that is not valid (199) then I will see the validation but if I just go into the box and tab out nothing happens.
I want to be able to go into the empty box and then tab out and see a "required message"
Is this still possible?
<EditForm EditContext="_editContext" OnValidSubmit="@SubmitValidForm"> <FluentValidationValidator @ref="_fluentValidationValidator" /> <ValidationSummary /> <p> <label>First Name: </label> <InputText @bind-Value="_person.FirstName" @onblur="() => ValidateField(nameof(_person.FirstName))" /> <ValidationMessage For="@(() => _person.FirstName)" /> </p>