Blazor DataAnnotations 比较验证冲突与浏览器自动完成功能

问题描述 投票:0回答:1

我有一个 Blazor 服务器应用程序,其中有一个包含两个密码输入的表单:“新密码”和“确认密码”。我正在使用 DataAnnotations

Compare
属性来验证两者是否匹配。我还尝试了实验性 NuGet 包
CompareProperty
中的
Microsoft.AspNetCore.Components.DataAnnotations.Validation
属性,但行为是相同的。

下面的示例页面能够在 Chrome 和 Edge 中重现该错误。测试步骤:

  1. 使用浏览器密码生成工具生成随机密码(在 Chrome 中,右键单击 -> 建议密码...)。两个密码字段都应使用生成的密码自动填写。
  2. 在“新密码”字段中,在末尾添加一个字符。这也会更新“确认密码”中的值,因此值确实匹配,但会触发验证失败。
  3. 要消除验证失败,请删除“确认密码”中的最后一个字符,按 Tab 键退出该字段,然后返回到该字段并重新添加相同的字符。这一次,验证成功了。

根据个人经验,我有时会在 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; }
    }
}
c# blazor data-annotations
1个回答
0
投票

您可能需要触发验证 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; }
    }
}

结果:

© www.soinside.com 2019 - 2024. All rights reserved.