Martin Andersen
Martin Andersen

Reputation: 2730

Reusable validation in Blazor WASM

I want to ask if there is a way for package the following code into a reusable component. The code is in the event handler of HandleValidSubmit on form submission.

        _accountValidator.ClearErrors();
        if (!string.IsNullOrEmpty(SelectedAgreement.Account))
        {
            if (SelectedAgreement.ProvisionAccountTypeId == (int) ProvisionAccountTypeEnum.CD_IDENT &&
                SelectedAgreement.Account.Length != 5)
            {
                var errors = new Dictionary<string, List<string>>
                {
                    {
                        nameof(SelectedAgreement.Account),
                        new List<string> {"CD Ident requires a 5 digit account number"}
                    }
                };
                _accountValidator.DisplayErrors(errors);
                return false;
            }

            if (SelectedAgreement.ProvisionAccountTypeId == (int) ProvisionAccountTypeEnum.VP_Account &&
                SelectedAgreement.Account.Length > 15)
            {
                var errors = new Dictionary<string, List<string>>
                {
                    {
                        nameof(SelectedAgreement.Account),
                        new List<string> {"VP Account number has a max length of 15"}
                    }
                };
                _accountValidator.DisplayErrors(errors);
                return false;
            }
        }

I know about fluent validation, but I have a lot of code using data attributes.

Upvotes: 0

Views: 109

Answers (2)

Nicola Biada
Nicola Biada

Reputation: 2800

You can write an AbstractValidatableObject from your model. Following an example:

public class PersonViewModel : AbstractValidatableObject
    {
        private PersonViewModel()
        {
        }

        public string FullName { get; set; }

        [Key]
        public int Id { get; set; }
        public string Code { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public override async Task<IEnumerable<ValidationResult>> ValidateAsync(ValidationContext validationContext,
         CancellationToken cancellation)
        {
            var errors = new List<ValidationResult>();

            if (LastName.StartsWith("Martin"))
            {
                errors.Add(new ValidationResult(ErrorConstants.NameOutOfScope, new[] { nameof(Person.LastName) }));
            }

            return errors;
        }
    }

when you call the Validate on the context the override method will be executed.

Upvotes: 0

Neil W
Neil W

Reputation: 9162

I don't think you can pass the CustomValidator (_accountValidator) around so I think your calls to ClearErrors and DisplayErrors will have to stay in the component where your CustomValidator sits.

That doesn't mean you can't send the edit model "SelectedAgreement" off to a reusable piece of code to return a Dictionary<string, List<string>> back to you for displaying on the CustomValidator component.

Some additional info:

https://learn.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-5.0

Upvotes: 1

Related Questions