我有一个 Blazor 服务器应用程序,其中有一个包含两个密码输入的表单:“新密码”和“确认密码”。我正在使用 DataAnnotations
Compare
属性来验证两者是否匹配。我还尝试了实验性 NuGet 包 CompareProperty
中的 Microsoft.AspNetCore.Components.DataAnnotations.Validation
属性,但行为是相同的。
下面的示例页面能够在 Chrome 和 Edge 中重现该错误。测试步骤:
根据个人经验,我有时会在 Chrome 建议的密码末尾添加额外的字符,主要是为了满足生成的密码无法满足的复杂性要求。因此,如果我的用户也这样做,这种表单行为将会出现问题。有人知道这是怎么回事以及如何解决吗?
索引.剃刀:
@page "/"
@using System.ComponentModel.DataAnnotations;
<PageTitle>Index</PageTitle>
<EditForm name="passwordForm" Model="MyModel" OnSubmit="@SubmitPasswordForm">
<DataAnnotationsValidator />
<div class="form-group">
<label for="NewPassword">New Password</label>
<InputText @bind-Value="MyModel.NewPassword" class="form-control" id="NewPassword" name="NewPassword" type="password" autocomplete="new-password"></InputText>
<ValidationMessage For="@(() => MyModel.NewPassword)" />
</div>
<div class="form-group">
<label for="ConfirmNewPassword">Confirm Password</label>
<InputText @bind-Value="MyModel.ConfirmPassword" class="form-control" id="ConfirmNewPassword" name="ConfirmNewPassword" type="password" autocomplete="new-password"></InputText>
<ValidationMessage For="@(() => MyModel.ConfirmPassword)" />
</div>
<input id="submitResetPassword" type="submit" class="btn btn-default" value="Reset Password" />
</EditForm>
@code {
private Model MyModel { get; set; } = new();
private void SubmitPasswordForm()
{
// Do something with the password
}
private class Model
{
[Required]
public string? NewPassword { get; set; }
[Required]
[Compare(nameof(NewPassword))]
// or [CompareProperty(nameof(NewPassword))]
public string? ConfirmPassword { get; set; }
}
}
您可能需要触发验证 onblur,如下所示:
@using System.ComponentModel.DataAnnotations;
<EditForm name="passwordForm" EditContext="@EC" OnSubmit="@SubmitPasswordForm">
<DataAnnotationsValidator />
<div class="form-group">
<label for="NewPassword">New Password</label>
<InputText @bind-Value="MyModel.NewPassword" class="form-control" id="NewPassword" name="NewPassword" type="password" autocomplete="new-password" onblur="@OnblurHandler"></InputText>
<ValidationMessage For="@(() => MyModel.NewPassword)" />
</div>
<div class="form-group">
<label for="ConfirmNewPassword">Confirm Password</label>
<InputText @bind-Value="MyModel.ConfirmPassword" class="form-control" id="ConfirmNewPassword" name="ConfirmNewPassword" type="password" autocomplete="new-password" ></InputText>
<ValidationMessage For="@(() => MyModel.ConfirmPassword)" />
</div>
<input id="submitResetPassword" type="submit" class="btn btn-default" value="Reset Password" />
</EditForm>
@code {
private Model MyModel { get; set; } = new();
private void SubmitPasswordForm()
{
// Do something with the password
}
protected override void OnInitialized()
{
EC = new EditContext(MyModel);
base.OnInitialized();
}
private void OnblurHandler()
{
EC.Validate(); // manually trigger the validation here
}
private EditContext EC { get; set; }
private class Model
{
[Required]
public string? NewPassword { get; set; }
[Required]
[Compare(nameof(NewPassword))]
// or [CompareProperty(nameof(NewPassword))]
public string? ConfirmPassword { get; set; }
}
}