Dataannotations for list in blazor page

Viewed 1684

I use the following to do validations on a form in blazor(server)

<EditForm Model="@place" OnValidSubmit="HandleValidSubmit" Context="placesEdit" >
<DataAnnotationsValidator />
 <InputText @bind-Value="place.Name"/>
<ValidationMessage For="() => place.Name" />
</EditForm>
@{place=new Place(); }

the property Name as a [required] - Attribute. This works fine. When submitting the form I see the error message and the HandleValidSubmit isn't called

But when I try to do the same with a List the validation isn't happening. No error is displayed and HandleValidSubmit is called instead even if the requirements are not met:

<EditForm Model="@places" OnValidSubmit="HandleValidSubmit" Context="placesEdit" >
<DataAnnotationsValidator />
 @foreach(var place in places) {
   <InputText @bind-Value="place.Name"/>
   <ValidationMessage For="() => place.Name" />
}
</EditForm>
@{places=new List<Place>(); }

What has do be done that the Validator also works in the loop?

1 Answers

Try if this helps:

  1. Add the Microsoft.AspNetCore.Components.DataAnnotations.Validation NuGet package.
  2. Replace your DataAnnotationsValidator with ObjectGraphDataAnnotationsValidator
    • You can check if your issue gets resolved with Step 2. If not, continue to Step 3.
  3. Annotate your list property with ValidateComplexType.
    • You will need to create a class that will contain your list property.

check the docs for more information: https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation#nested-models-collection-types-and-complex-types


If you're using IValidatableObject like me, the above solution won't work. The workaround is to create another property to link the validation into.

e.g.

public class MyModel : IValidatableObject
{
    public List<Place> Places { get; } = new List<Place>();
    public object PlacesValidation { get; }
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var isValid = ...;
        if (isValid)
            yield return new ValidationResult("Places is invalid.", new[] { nameof(PlacesValidation ) });
    }
}
<ValidationMessage For="() => Model.PlacesValidation"/>
Related