context.Validate() and CustomValidator

prof cegep 41 Reputation points
2022-04-20T21:41:21.703+00:00

Since I use this condition in button :

<button type="submit" disabled="@(!context.IsModified() || !context.Validate())" class="btn btn-primary edit-btn">@Localizer["Edit_Save"]</button>

My custom validator not display in the razor page :

<EditForm Model="[@](/users/na/?userId=17b9b963-0000-0003-0000-000000000000)" OnValidSubmit="@HandleValidSubmit" OnInvalidSubmit="@HandleInvalidSubmit">    
    <DataAnnotationsValidator />  
    <CustomValidator [@](/users/na/?userId=9c49c77f-4001-0003-0000-000000000000)="customValidation" />  
    <ValidationSummary></ValidationSummary>  
    <div class="form-group row">  

Razor code

                var Result = await UserDataService.UpdateUser(User);    
                if (Result.Item1 != null)  
                {  
                    NavigationManager.NavigateTo("/summary");  
                }  
                else  
                {  
                    if (Result.Item2.ToString().Contains(SafetyStd.Shared.Constants.RequireUniqueEmail))  
                    {  
                        errors.Add(nameof(User.Email), new() { "Adresse courriel existante..." });  
                    }  
                    if (Result.Item2.ToString().Contains(SafetyStd.Shared.Constants.DuplicateUserName))  
                    {  
                        errors.Add(nameof(User.Email), new() { "Adresse courriel existante..." });  
                    }  
                    if (errors.Any())  
                    {  
                        customValidation?.DisplayErrors(errors);  
                    }  
                }  
            StateHasChanged();   

With F12 everything works normally.

Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,406 questions
{count} votes

Accepted answer
  1. Zhi Lv - MSFT 32,021 Reputation points Microsoft Vendor
    2022-04-29T05:53:45.953+00:00

    Hi @prof cegep ,

    The minute this line is inserted, the custom error not working. Can you try it on your side?

    <button type="submit" disabled="@(!editContext.IsModified() || !editContext.Validate())" class="btn btn-primary edit-btn">@Localizer["Edit_Save"]</button>    
    

    Yes, if I use the above code to enable/disable the submit button, it will show the strange behavior : the DataAnnotations validation works well, and we can enable/disable the submit button based on the DataAnnotations validation result, but when submit the form, event the CustomValidator 's method executed, it will not show the error message. This is your problem, right?

    To this issue, if you set a break point in the OnValidationRequested event handler, you can see that each time change the field and call the validate method, it will trigger this event, and the message store will clear. So, it will cause the custom error message disappear.

         CurrentEditContext.OnValidationRequested += (s, e) =>  
             messageStore.Clear();  
    

    To solve this issue, you could try to remove the above event handler from the CustomValidator. Then the result as below:

    197560-1.gif


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Dillion

    0 comments No comments

3 additional answers

Sort by: Most helpful
  1. prof cegep 41 Reputation points
    2022-04-28T02:53:37.793+00:00

    Hello Dillon,

    Thanks a lot to take your time about my issue.

    I try it but in your <EditForm...> can you insert @Георгий Георгиевский .Validate() :

    @editContext.Validate()  
    

    The minute this line is inserted, the custom error not working. Can you try it on your side?

    I need it to enable/disable my submit button like this :

    <button type="submit" disabled="@(!editContext.IsModified() || !editContext.Validate())" class="btn btn-primary edit-btn">@Localizer["Edit_Save"]</button>

    0 comments No comments

  2. prof cegep 41 Reputation points
    2022-04-21T18:14:47.997+00:00

    Hello ZhiLv

    Sure this is my custom validator

    public class CustomValidator : ComponentBase    
    
    {  
        private ValidationMessageStore messageStore;  
    
        [CascadingParameter]  
        private EditContext CurrentEditContext { get; set; }  
    
        protected override void OnInitialized()  
        {  
            if (CurrentEditContext == null)  
            {  
                throw new InvalidOperationException(  
                    $"{nameof(CustomValidator)} requires a cascading " +  
                    $"parameter of type {nameof(EditContext)}. " +  
                    $"For example, you can use {nameof(CustomValidator)} " +  
                    $"inside an {nameof(EditForm)}.");  
            }  
    
            messageStore = new ValidationMessageStore(CurrentEditContext);  
    
            CurrentEditContext.OnValidationRequested += (s, e) =>  
                messageStore.Clear();  
            CurrentEditContext.OnFieldChanged += (s, e) =>  
                messageStore.Clear(e.FieldIdentifier);  
        }  
    
        public void DisplayErrors(Dictionary<string, List<string>> errors)  
        {  
            foreach (var err in errors)  
            {  
                messageStore.Add(CurrentEditContext.Field(err.Key), err.Value);  
            }  
    
            CurrentEditContext.NotifyValidationStateChanged();  
        }  
    
        public void ClearErrors()  
        {  
            messageStore.Clear();  
            CurrentEditContext.NotifyValidationStateChanged();  
        }  
    }  
    

    I just have to put @Георгий Георгиевский .Validate() anywhere in razor page and my custom validator not work

    <EditForm Model="@User" OnValidSubmit="@HandleValidSubmit" OnInvalidSubmit="@HandleInvalidSubmit">  
        <DataAnnotationsValidator />  
        <CustomValidator @ref="customValidation" />  
        <ValidationSummary></ValidationSummary>  
    
             @context.Validate()  
    

    ...

    0 comments No comments

  3. Zhi Lv - MSFT 32,021 Reputation points Microsoft Vendor
    2022-04-27T06:10:08.52+00:00

    Hi @prof cegep ,

    I just have to put @Георгий Георгиевский .Validate() anywhere in razor page and my custom validator not work

     <EditForm Model="[@](/users/na/?userId=17b9b963-0000-0003-0000-000000000000)" OnValidSubmit="@HandleValidSubmit" OnInvalidSubmit="@HandleInvalidSubmit">  
    
          <DataAnnotationsValidator />  
          <CustomValidator [@](/users/na/?userId=9c49c77f-4001-0003-0000-000000000000)="customValidation" />  
          <ValidationSummary></ValidationSummary>  
               [@](/users/na/?userId=fc7fd616-59a7-460b-8ea5-4daa131585c2).Validate()  
    

    Whether this problem is resolved or not? If not, the issue might relate that EditForm Model and the callbacks for handling form submission.

    To solve the above issue, let review some basic knowledge: ASP.NET Core Blazor forms and validation

    In Asp.net core Blazor, when binding an EditForm, we can assigning to either an EditForm.Model or an EditForm.EditContext, and then bind a form to data. But don't use both for the same form. Then to validate the form, we need to call the EditContext.Validate in the event handler method, so in this scenario, we need to assign an EditForm.EditContext to the EditForm, instead of an EditForm.Model.

    Then, the EditForm provides the following callbacks for handling form submission:

    • Use OnValidSubmit to assign an event handler to run when a form with valid fields is submitted.
    • Use OnInvalidSubmit to assign an event handler to run when a form with invalid fields is submitted.
    • Use OnSubmit to assign an event handler to run regardless of the form fields' validation status. The form is validated by calling EditContext.Validate in the event handler method. If Validate returns true, the form is valid.

    So, to solve your issue, you need to change your code as below:

    1. change the Model to EditContext,
    2. calling the EditContext.Validate method in the OnInvalidSubmit event or OnSubmit event:
       <EditForm EditContext="@context" OnValidSubmit="@HandleValidSubmit" OnInvalidSubmit="@HandleInvalidSubmit">  
           <DataAnnotationsValidator />  
           <CustomValidator @ref="customValidation" />  
           <ValidationSummary></ValidationSummary>  
      
      Here is an simple sample, the result like this: if I select the "Defense" option, it will show the custom validate error.

    196700-1.gif

    You can check the source code from here: 196769-sourcecode.txt


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Dillion

    0 comments No comments