Home > Software engineering >  How to validate all properties in a model at the same time?
How to validate all properties in a model at the same time?

Time:09-10

I have a Blazor application. In this application I have several models with various ValidationAttributes.

To validate these models I use an EditForm from Microsoft.AspNetCore.Components.Forms. On this form there is a parameter Called EditContext where I call the Validate() method to validate my models.

The validation itself works fine. However the order of when validations are run seems to be based on the type, like this:

  1. Required
  2. Other(Like Range)
  3. IValidatableObject

This results in Required validations being validated first and only after these are valid in the model the other validations are running.

What I want is for all validations to run at the same time.

Does anyone know how to achieve this in Blazor?

Thanks

CodePudding user response:

What I want is for all validations to run at the same time.

Not sure what you mean? All registered validations are run when you call Validate. There's has to be a sequence. If you want to change the sequence then you need to write your own validator.

the order of when validations are run seems to be based on the type

Validate on the edit context looks like this. It simply invokes any delegates registered with the OnValidationRequested event.

    public event EventHandler<ValidationRequestedEventArgs>? OnValidationRequested;

    public bool Validate()
    {
        OnValidationRequested?.Invoke(this, ValidationRequestedEventArgs.Empty);
        return !GetValidationMessages().Any();
    }

DataAnnotationsValidator or whatever validator you use registers a handler on this event.

In your case the validator is finding fields to validate by searching through the properties in the Model (referenced in EditContext) for specifc attributes. The first attribute it looks for is Required, ....

CodePudding user response:

There is logics in the validation... Do you expect a StringLength validator to run at the same time a Required validator runs, effectively checking the length of an empty string ? Shoudn't we first verify that the users enter some text before we check the length of the text. What you request is not reasonable, but it is to some extent, doable, simply by doing the validation yourself.

See this code:

<button @onclick="Validate" type="submit">Save</button>




private void Validate()
    {
        
        var fieldIdentifier = new FieldIdentifier(Model, "Name");

        var propertyValue = Model.Name;

        messages.Clear(fieldIdentifier);

        if (string.IsNullOrEmpty(propertyValue))
        {

            messages.Add(fieldIdentifier, "Name is required...");
        }
       
        if (propertyValue is not null && propertyValue.Length > 10)
        {

            messages.Add(fieldIdentifier, "Name cannot be longer than 10 characters...");


        }
        
        EditContext.NotifyValidationStateChanged();
    }

The code above check the user's input. If no value entered only the first if statement is executed, and the message "Name is required..." is displayed. If the user entered a string longer than 10, only the second if statement is executed, displaying the "Name cannot be longer than 10 characters..." message. They can't both execute on the same time.

But, when required is not involved, it is possible to run both validators at the same time. Example:

private void Validate()
    {
        
        var fieldIdentifier = new FieldIdentifier(Model, "Name");

        var propertyValue = Model.Name;

        messages.Clear(fieldIdentifier);

        if (propertyValue.StartsWith("e"))
        {

            messages.Add(fieldIdentifier, "Please don't start a name with the letter e...");
        }
       
        if (propertyValue is not null && propertyValue.Length > 10)
        {

            messages.Add(fieldIdentifier, "Name cannot be longer than 10 characters...");


        }
        
        EditContext.NotifyValidationStateChanged();
    }

the result of the method above is:

Please don't start a name with the letter e...

Name cannot be longer than 10 characters...

If you enter the string, as for instance: enetxxxxxxxxxxxxxx

And this is how you can make your validation executed at the same time. But not with Required. Do you understand why ;}

  • Related