1

I have a simple model called FooModel that has a single string property called Text.

I am attempting to use DataAnnotationsValidator to validate a collection of Models that are dynamically added to the EditForm

The chained binding and the ValidationSummary and ValidationMessage works outside of a loop. See Example 1

But using a loop, Example 2, the form submitting always validates as true and no errors are displayed in the ValidationSummary nor ValidationMessage.

I guess I could have an EditForm per iteration and that may solve it, but I was trying to get it in a single EditForm.

If I add a CascadingParameter of EditForm to the ListComponent and subscribe to OnValidationRequested I see all the latest values for the Model in question, but it doesn't seem to bubble up to the Page.

Any help or suggestions are appreciated.

Model

public class FooModel
{
    [MinLength(2)]
    public string? Text { get; set; }
}

Page

// Example 1

<EditForm Model=@_fooModel OnValidSubmit=@OnValidSubmit OnInvalidSubmit=@OnInvalidSubmit>
   <DataAnnotationsValidator />
      <ValidationSummary />
      <InputComponent @bind-Value=@_fooModel.Text />
      <button type="submit">Submit</button>
</EditForm>

// Example 2

<EditForm Model=@_fooModels OnValidSubmit=@OnValidSubmit OnInvalidSubmit=@OnInvalidSubmit>
   <DataAnnotationsValidator />
      <ValidationSummary />
      <ListComponent @bind-Values=@_fooModels />
      <button type="submit">Submit</button>
</EditForm>

@code {

   private FooModel _fooModel = new() { Text = "z" };
   private List<FooModel> _fooModels = new() { 
      new() { Text = "a" },
      new() { Text = "b" },
      new() { Text = "c" } 
   };

}

List Component

@{
    foreach (var value in Values)
    {
        <InputComponent @[email protected] />
    }
}

@code {

   [Parameter]
   public required List<FooModel> Values { get; set; }

   [Parameter]
   public EventCallback<List<FooModel>> ValuesChanged { get; set; }

}

InputComponent

<input type="text" value=@value @onchange=@OnInput />
<ValidationMessage For=@ValueExpression />

@code {

    private string? value;
    
    [Parameter]
    public Expression<Func<string>> ValueExpression { get; set; } = default!;
   
    [Parameter]
    public string? Value { get; set; }

    [Parameter]
    public EventCallback<string> ValueChanged { get; set; }
    
    private async Task OnInput(ChangeEventArgs e)
    {
        value = e?.Value?.ToString();
        await ValueChanged.InvokeAsync(value);
    }
}
3
  • 2
    DataAnnotationsValidator doesn't support complex objects. Take a look at Fluent Validation. See docs.fluentvalidation.net/en/latest/blazor.html Commented Aug 3, 2024 at 21:46
  • 1
    @MrCakaShaunCurtis, reply as an answer and I can give you the credit. I was looking at that as an option, but it is clear you're correct on DataAnnotationsValidator inability to support complex object. Thanks for the push. Commented Aug 6, 2024 at 13:18
  • 2
    Done. I've also provided a link to a simple Blazor implementation I use. Commented Aug 6, 2024 at 13:31

1 Answer 1

2

DataAnnotationsValidator doesn't support complex objects.

Take a look at Fluent Validation. See - Fluent Validation.

There are references to several Blazor implementations in the link. If you want to see a simple Blazor implementation there's the one I use here - https://github.com/ShaunCurtis/Blazr.FluentValidation.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.