How to reset custom validation errors when using editform in blazor razor page

蓝咒 提交于 2020-05-27 06:26:31

问题


I have an editform using an editcontext:

    <EditForm OnValidSubmit="HandleValidSubmit" EditContext="_editContext" Context="auth">
      <DataAnnotationsValidator />
      <input type="time" @bind-value="_foodTruck.EndDelivery" @onkeydown="@(q=>ResetValidation("EndDelivery"))" >
        <ValidationMessage For="() => _foodTruck.EndDelivery" />
      <input type="time" @bind-value="_foodTruck.StartDelivery" @onkeydown="@(q=>ResetValidation("StartDelivery"))" >
        <ValidationMessage For="() => _foodTruck.StartDelivery" />
      <input class="btn btn-default" type="submit" value="save" />
    </EditForm>

I do some custom validations in HandleValidSubmit:

EditContext _editContext = new EditContext(_foodTruck);
private async void HandleValidSubmit()
{
  var messageStore = new ValidationMessageStore(_editContext);
  if (_foodTruck.StartDelivery >= _foodTruck.EndDelivery)
  {
    messageStore.Add(_editContext.Field("EndDelivery"), "Bad time entered");
    _editContext.NotifyValidationStateChanged();
  }
 if (!_editContext.Validate()) return;
}

What now happens is that my custom error ("bad time entered") is displayed at the right position. The only issue is: That error does not disappear when I change the value. So HandleValidSubmit is never called again if I click onto the submit button.

I also tried emptying the validationerrors when modifying the fields:

   protected void ResetValidation(string field)
    {
        var messageStore = new ValidationMessageStore(_editContext);        
        messageStore.Clear(_editContext.Field(field));
        messageStore.Clear();
        _editContext.NotifyValidationStateChanged();
    }

This is called by onkeydown. But that doesn't seem to have an effect, either. The Errormessage does not disappear and so HandleValidSubmit isn't called either.


回答1:


I solved this by creating a new EditContext on Validation-reset. So I simply added the following line to the ResetValidation-Method:

  _editContext = new EditContext(_foodTruck);

But to be honest: That does not feel right. So I will leave this open for better answers to come (hopefully).




回答2:


I had same problem. I couldn't find straightforward solution. Workaround similar to below worked for me.

Modify EditForm as follows -

<EditForm EditContext="_editContext" OnSubmit="HandleSubmit">

@Code Block

EditContext _editContext;

ValidationMessageStore msgStore;

FoodTruck _foodTruck= new FoodTruck();

protected override void OnInitialized()
{
    _editContext = new EditContext(_foodTruck);
    msgStore = new ValidationMessageStore(_editContext);
}

void HandleSubmit()
{
    msgStore.Clear();
    if(_editContext.Validate()) // <-- Model Validation
    {
        if (_foodTruck.StartDelivery >= _foodTruck.EndDelivery) //<--Custom validation
        {
            msgStore = new ValidationMessageStore(_editContext);
            msgStore.Add(_editContext.Field("EndDelivery"), "Bad time entered");
        }
    }
}



回答3:


Add this.StateHasChanged() at the end of the event action so that it can render the ui elements again and remove the validation message.

EditContext _editContext = new EditContext(_foodTruck);
private async void HandleValidSubmit()
{
  var messageStore = new ValidationMessageStore(_editContext);
  if (_foodTruck.StartDelivery >= _foodTruck.EndDelivery)
  {
    messageStore.Add(_editContext.Field("EndDelivery"), "Bad time entered");
    _editContext.NotifyValidationStateChanged();
     this.StateHasChanged(); //this line
  }
 if (!_editContext.Validate()) return;
}

for the other one

protected void ResetValidation(string field)
{
        var messageStore = new ValidationMessageStore(_editContext);        
        messageStore.Clear(_editContext.Field(field));
        messageStore.Clear();
        _editContext.NotifyValidationStateChanged();
        this.StateHasChanged(); //this line
}

kindly let me know if it works




回答4:


Here's a code snippet that describes how you can add an error message to a ValidationMessageStore, and how to remove it when you change the value entered to a valid one. Just copy and run it. It should work. In this sample we check if the value of the EmailAddress is "OleAlbers@gmail.com", and if it is, we display the message: "Email already exists." Enter a new value, and the message is gone.

 @using System;
 @using System.Collections.Concurrent;
 @using System.Collections.Generic;
 @using System.ComponentModel.DataAnnotations;
 @using System.Linq;
 @using System.Reflection;

<h1>My articles</h1>

<p>Leave me a comment</p>


<EditForm EditContext="@EditContext" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />

<div class="form-group">
    <label for="name">Name: </label>
    <InputText Id="name" Class="form-control" @bind-Value="@Model.Name"> 
     </InputText>
    <ValidationMessage For="@(() => Model.Name)" />

</div>
<div class="form-group">
    <label for="body">Text: </label>
    <InputText Id="body" Class="form-control" @bind-Value="@Model.Text"> 
     </InputText>
    <ValidationMessage For="@(() => Model.Text)" />
</div>
<div class="form-group">
    <label for="body">Email: </label>
    <InputText Id="body" Class="form-control" @bind- 
                  Value="@Model.EmailAddress"></InputText>
    <ValidationMessage For="@(() => Model.EmailAddress)" />
</div>
 <p>

    <button type="submit">Save</button>

  </p>
 </EditForm>

 @code
 {

     private EditContext EditContext;
     private Comment Model = new Comment();
     ValidationMessageStore messages;

     protected override void OnInitialized()
     {
        EditContext = new EditContext(Model);
        EditContext.OnFieldChanged += EditContext_OnFieldChanged;
        messages = new ValidationMessageStore(EditContext);

        base.OnInitialized();
     }

     // Note: The OnFieldChanged event is raised for each field in the model
     private void EditContext_OnFieldChanged(object sender, 
                                                     FieldChangedEventArgs e)
    {

    if (TryGetValidatableProperty(e.FieldIdentifier, out var propertyInfo))
    {
        var propertyValue = propertyInfo.GetValue(e.FieldIdentifier.Model);

        if (e.FieldIdentifier.FieldName == nameof(Model.EmailAddress))
        {

            if ((string) propertyValue == "OleAlbers@gmail.com")
            {
                messages.Clear(e.FieldIdentifier);
                messages.Add(e.FieldIdentifier, "Email already exists");
            }
            else
            {
                messages.Clear(e.FieldIdentifier);
            }
        }
        EditContext.NotifyValidationStateChanged();
     }

  }

 private static bool TryGetValidatableProperty(in FieldIdentifier 
                          fieldIdentifier, out PropertyInfo propertyInfo)
 {
    var cacheKey = (ModelType: fieldIdentifier.Model.GetType(), 
      fieldIdentifier.FieldName);

    propertyInfo = cacheKey.ModelType.GetProperty(cacheKey.FieldName);


    return propertyInfo != null;
}

public async Task HandleValidSubmit()
{
    await Task.Run(() =>
    {
        Console.WriteLine("Saving...");
        Console.WriteLine(Model.Name);
        Console.WriteLine(Model.Text);
    });

 }

 public class Comment
{
    [Required]
    [MaxLength(10)]
    public string Name { get; set; }

    [Required]
    public string Text { get; set; }

    [Required]
    [EmailAddress]
    [DataType(DataType.EmailAddress)]
    public string EmailAddress { get; set; }
 }

}

Hope this works...



来源:https://stackoverflow.com/questions/60917323/how-to-reset-custom-validation-errors-when-using-editform-in-blazor-razor-page

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!