英文:
Blazor and fluentvalidation clear validation messages
问题
我有一个非常简单的模型,有一个开始时间和结束时间:
public class OutputModel
{
public event Action<double> OnStartChanged;
public event Action<double> OnEndChanged;
public double Start { get; private set; }
public double End { get; private set; }
public string StartProxy { get; set; }
public string EndProxy { get; set; }
}
我使用EditForm来显示输入框,用户可以编辑这些时间。输入框与StartProxy和EndProxy属性绑定,以便我可以在开始或结束框中输入有效时间时触发事件。
<EditForm Model="@Model">
<div class="m-2 selector">
<FluentValidationValidator @ref="Model.Validator" />
<div class="info-group mb-1">
<label for="start">Start</label>
<InputText id="start" class="form-control form-control-sm" Value="@Model.StartProxy" ValueChanged="Model.StartChanged" ValueExpression="() => Model.StartProxy" />
</div>
<ValidationMessage For="() => Model.StartProxy" />
<div class="info-group mb-1">
<label for="end">Einde</label>
<InputText id="end" class="form-control form-control-sm" Value="@Model.EndProxy" ValueChanged="Model.EndChanged" ValueExpression="() => Model.EndProxy" />
</div>
<ValidationMessage For="() => Model.EndProxy" />
<div class="info-group mb-1">
<label for="duration">Duur</label>
<input id="duration" disabled="true" class="form-control form-control-sm" @bind="Model.Duration">
</div>
</div>
</EditForm>
这样做也需要我手动验证。因此,我创建了4个规则集,当StartProxy或EndProxy更改时手动调用:
- 用于检查StartProxy格式的规则集
- 用于检查EndProxy格式的规则集
- 用于检查Start是否在End之前的规则集
- 用于检查End是否在Start之后的规则集
我有3和4是因为我想要根据用户当前使用的框在开始框和结束框显示不同的消息。
验证开始的代码如下(结束类似,但属性不同):
public void StartChanged(string value)
{
StartProxy = value;
var validator = new OutputModelValidator();
// 首先检查开始的格式
var result = validator.Validate(this, options => options.IncludeRuleSets(OutputModelValidator.StartFormatRules));
if (result.Errors.Any())
{
return;
}
// 如果格式正确,则可以设置开始时间
Start = StartProxy.ToTimeSpan().Value.TotalSeconds;
StartProxy = TimeSpan.FromSeconds(Start).ToString(TimeFormat);
SetDuration();
// 检查结束是否正确
if (validator.Validate(this, options => options.IncludeRuleSets(OutputModelValidator.EndFormatRules)).Errors.Any())
{
// 结束有错误,所以我们结束这里
return;
}
// 开始和结束的格式都正确,现在从结束的角度检查它们的组合
if (!validator.Validate(this, options => options.IncludeRuleSets(OutputModelValidator.StartBeforeEndRules)).Errors.Any())
{
// 开始和结束都不错,所以传播值
OnStartChanged?.Invoke(Start);
OnEndChanged?.Invoke(End);
}
}
所以首先我检查更改的框的格式。如果有效,我检查“其他”框是否包含错误(因为两者当然都可能错误)。当检查通过后,我检查开始和结束的组合。
基本上这很好用,但问题是:
- 结束框显示:“00:25.200”
- 我在开始框中输入:“00:30.123”
- 代码验证并在开始框中显示错误:“开始不在结束之后”
- 现在我在结束框中输入:“00:35.200”
- 代码验证并一切正常。
- 我的开始框仍然显示消息:“开始不在结束之后”
因此,我的问题是:我如何清除“其他”属性的消息。还是我需要完全不同的方法。当然欢迎建议。非常感谢。
英文:
I have a very simple model with a starttime and endtime:
public class OutputModel
{
public event Action<double> OnStartChanged;
public event Action<double> OnEndChanged;
public double Start { get; private set; }
public double End { get; private set; }
public string StartProxy { get; set; }
public string EndProxy { get; set; }
}
I'm using an EditForm to display inputboxes in which the user can edit these times. The inputboxes are bind to the StartProxy and EndProxy properties in such a way that I can trigger the events whenever a valid time is entered in either the start or end box.
<EditForm Model="@Model">
<div class="m-2 selector">
<FluentValidationValidator @ref="Model.Validator" />
<div class="info-group mb-1">
<label for="start">Start</label>
<InputText id="start" class="form-control form-control-sm" Value="@Model.StartProxy" ValueChanged="Model.StartChanged" ValueExpression="() => Model.StartProxy" />
</div>
<ValidationMessage For="() => Model.StartProxy" />
<div class="info-group mb-1">
<label for="end">Einde</label>
<InputText id="end" class="form-control form-control-sm" Value="@Model.EndProxy" ValueChanged="Model.EndChanged" ValueExpression="() => Model.EndProxy" />
</div>
<ValidationMessage For="() => Model.EndProxy" />
<div class="info-group mb-1">
<label for="duration">Duur</label>
<input id="duration" disabled="true" class="form-control form-control-sm" @bind="Model.Duration">
</div>
</div>
</EditForm>
Doing this also requires me to validate things manually. So I have created 4 rulesets which I call manually when either StartProxy or EndProxy changes:
- A ruleset to check the format of StartProxy
- A ruleset to check the format of EndProxy
- A ruleset to check if Start is before End
- A ruleset to check if End is after Start
I have 3 and 4 because I want different messages at the startbox and endbox depending on the box that is currently used by the user.
The code that validates the start is this (the end is more or less the same, but different properties):
public void StartChanged(string value)
{
StartProxy = value;
var validator = new OutputModelValidator();
// First check the format of the start
var result = validator.Validate(this, options => options.IncludeRuleSets(OutputModelValidator.StartFormatRules));
if (result.Errors.Any())
{
return;
}
// Start can be set if the format is ok
Start = StartProxy.ToTimeSpan().Value.TotalSeconds;
StartProxy = TimeSpan.FromSeconds(Start).ToString(TimeFormat);
SetDuration();
// Check if end is correct
if (validator.Validate(this, options => options.IncludeRuleSets(OutputModelValidator.EndFormatRules)).Errors.Any())
{
// End contains errors, so were done here
return;
}
// Start and end are 'format valid', now check their combination from an end perspective
if (!validator.Validate(this, options => options.IncludeRuleSets(OutputModelValidator.StartBeforeEndRules)).Errors.Any())
{
// Start is good and end is good so propagate the values
OnStartChanged?.Invoke(Start);
OnEndChanged?.Invoke(End);
}
}
So first I'm checking the format of the box that is changed. When valid I check if the 'other' box contains errors (because both can be wrong ofcourse). When good, then I check the combination for start and end.
In basic this works fine, but the problem is the following:
- The endbox shows: '00:25.200'
- I type '00:30.123' in the startbox
- The code validates and gives an error at the startbox: 'Start not after end'
- I now type '00:35.200' in the endbox
- The code validates and everything is fine.
- My startbox still shows the message: 'Start not after end'
So my question is: how can I clear the messages for the 'other' property. Or do I need a completely different approach. Suggestions are welcome ofcourse.
Many thanks in advance
答案1
得分: 0
Sure, here's the translated code part:
在不断搜索和搜索,以及更多的搜索之后(并在此线程中找到答案:https://stackoverflow.com/questions/60917323/how-to-reset-custom-validation-errors-when-using-editform-in-blazor-razor-page),我终于修复了这个问题。
首先,我的问题出在与编辑表单的绑定上。我之前写的是:
<EditForm Model="@Model">
应该改成:
<EditForm EditContext="@Model.EditContext">
然后,在所有验证完成后,我现在调用:
EditContext.NotifyFieldChanged(new FieldIdentifier(this, nameof(StartProxy)));
这样告诉 Blazor 更新其他字段(在本例中是 StartProxy)。
英文:
After searching and searching and much more searching (and finding the answers in this thread: https://stackoverflow.com/questions/60917323/how-to-reset-custom-validation-errors-when-using-editform-in-blazor-razor-page) I finally was able to fix this.
First problem was my binding to the editform. I had this:
<EditForm Model="@Model">
which should be this:
<EditForm EditContext="@Model.EditContext">
Then in the code after all the validations are done I now call this:
EditContext.NotifyFieldChanged(new FieldIdentifier(this, nameof(StartProxy)));
So you tell Blazor to update the other field (in this case StartProxy).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论