问题
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