服务器端Blazor验证未更新UI

时间:2020-04-13 16:01:05

标签: blazor

我有一个Blazor组件,它代表一个表单,在提交之前需要执行一些昂贵的验证,以确保服务器上数据点的唯一性。我试图以此文档为灵感:https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-3.1

似乎更好的文档位于Microsoft文档路线图上:https://github.com/dotnet/AspNetCore.Docs/issues/17377

我的组件看起来像这样:

<EditForm Model="@form" OnValidSubmit="@Submit">
    <InputText @bind-Value="form.DataPoint" />
    <ValidationMessage For="() => form.DataPoint" />

    <button type="submit">Go!</button>
</EditForm>

@code {
    private Form form = new Form();
    private EditContext editContext;

    protected override void OnInitialized() 
    {
        editContext = new EditContext(form);
    }

    private async Task Submit()
    {
        var isValid = editContext.Validate() && await ServerValidate(editContext);
        if (isValid) 
        { 
            // do stuff 
        }
    }

    private async Task<bool> ServerValidate(EditContext editContext)
    {
        var form = (Form)editContext.Model;
        var validationErrors = new ValidationMessageStore(editContext);
        var isDataPointCollision = await SomeService.CheckUniqueness(form.DataPoint);
        if (isDataPointCollision)
        {
            var field = new FieldIdentifier(form, nameof(Form.DataPoint));
            validationErrors.Add(field, "This data point already exists, please type a different one");
            editContext.NotifyValidationStateChanged();
            return false;
        }
        return true;
    }
}

我的验证代码可以正常工作,检测到冲突并阻止提交表单。但是,UI并未通过<ValidationMessage [...] />组件按预期进行更新。根本不会发生UI更新,也不会显示任何验证消息。我也尝试过此组件:

<ValidationSummary Model="@form" />

无济于事。

服务器上或客户端JS中都没有错误。

我是用这种方法吠叫了错误的树,还是错过了某个地方的连接?有没有更好的方法来完成我想要做的事情?

3 个答案:

答案 0 :(得分:2)

您创建(并更新)未附加到UI窗体的EditContext。

将第一行更改为(注意:无模型):

 <EditForm EditContext="editContext"  OnValidSubmit="Submit">

您的其余代码可以保持原样,不需要StateHasChanged()或其他任何东西。

在您链接到的第一个文档页面上,搜索"_editContext"

答案 1 :(得分:1)

验证后致电StateHasChanged

    private async Task Submit()
    {
        var isValid = editContext.Validate() && await ServerValidate(editContext);
        if (isValid) 
        { 
            // do stuff 
        }
        StateHasChanged();
    }

注意:如果您可以访问其中的组件,则可以在editContext.NotifyValidationStateChanged()内部调用它。

答案 2 :(得分:1)

汉克的答案是正确的。一些补充

  1. <DataAnnotationsValidator />下添加<ValidationSummary /><EditForm>,以进行由模型注释驱动的各个字段的验证,并根据需要添加表单摘要错误消息(除了每个字段之外,还包含表单上方的错误)。 / li>
  2. 一旦在字段(validationErrors.Add(field, "This data point already exists, please type a different one");中添加了一条消息,该消息将继续存在,以后的“提交”将被视为无效。
  3. 由于上面的验证错误以及它与OnInvalidSubmit()的配对,此时只有OnValidSubmit()会触发。需要清除该错误后才能进行常规处理。
  4. 我只找到一种蛮力清除错误的方法,那就是使用ClearError()方法重新初始化EditContext
    public void ClearErrors()
    {
        _editContext = new EditContext(form);
        isSubmitButtonDisabled = false;
        showClearErrors = false;
    }

然后我将其连接到一个在showClearErrors=true时显示的按钮,并禁用“提交”按钮。如果有更好的方法来清除错误,我将不知所措。