I use Razor pages and want to specify a rule, when at least one selectItem should be selected for multiply select element.
I have the following rule:
public class MailRangeValidator : AbstractValidator<MailsRangeModel>
{
public MailRangeValidator()
{
RuleFor(x => x.SelectedFolders)
.Must(x => x.Count() > 0)
//.Must(coll => coll.Any(item => !string.IsNullOrWhiteSpace(item)))
.WithMessage("At least one folder should be selected");
}
}
and the following strings in the Program.cs
:
builder.Services.AddFluentValidation();
builder.Services.AddTransient<IValidator<MailsRangeModel>, MailRangeValidator>();
property SelectedFolders
is declared as:
[BindProperty]
public string[] SelectedFolders { get; set; }
and the following select
element:
<select asp-for="SelectedFolders" asp-items="Model.Folders" size="10"></select>
when I don't select any element (leave select
as empty), on my OnPostShowDataAsync
:
public async Task<IActionResult> OnPostShowDataAsync()
{
if (!ModelState.IsValid)
{
return new PageResult();
}
ModelState.IsValid
is true
. Why and how to fix it?
CodePudding user response:
AddFluentValidation must be called directly after calling AddMvc.
AddFluentValidation extension method inside the ConfigureServices method (which requires a using FluentValidation.AspNetCore). This method must be called directly after calling AddMvc.
builder.Services.AddMvc().AddFluentValidation();
builder.Services.AddTransient<IValidator<MailsRangeModel>, MailRangeValidator>();
CodePudding user response:
from documentation https://docs.fluentvalidation.net/en/latest/aspnet.html:
Configuration for use with ASP.NET Razor Pages and PageModels is exactly the same as with MVC above, but with the limitation that you can’t define a validator for the whole page-model, only for models exposed as properties on the page model.
so, problem is solved by the following way:
private List<string> Validate()
{
MailRangeValidator validator = new MailRangeValidator();
var result = validator.TestValidate(this);
return result.Errors.Select(a => a.ErrorMessage).ToList();
}
after it we check whether Errors exists, push it to ModelState and return to client:
var errors = Validate();
if (errors.Count > 0)
{
foreach (var error in errors)
{
ModelState.AddModelError("", error);
}
await FillDataAsync();
return Page();
}