簡體   English   中英

如何在 Blazor 服務器應用程序中驗證模型而不觸發驗證消息?

[英]How to validate a model in Blazor server app without triggering validation messages?

我正在開發一個 Blazor 服務器應用程序,該應用程序分幾個步驟收集用戶信息。 父頁面創建一個模型(我們稱之為 MainModel),它是來自子組件中使用的模型的數據集合,父將該模型作為級聯參數傳遞給子級,子級收集更多信息並填充該模型中的匹配參數。

加載組件時,它會加載自己的模型。 當輸入被修改時,我需要檢查 ChildModel 並將其添加到 MainModel 如果它通過驗證。 根據 Blazor 文檔,我將 FieldChanged 事件用於 EditContext。


    <EditForm EditContext="editContext">
    <DataAnnotationsValidator/>
    <div class="col-md-6">
        <label for="FirstName" class="form-label">First Name</label>
        <InputText type="text" @bind-Value="Model.FirstName" class="form-control" 
     name="FirstName"/>
        <ValidationMessage For="@(() => Model.FirstName)" />
    </div>
    <div class="col-md-3">
        <label for="LastName" class="form-label">Last Name</label>
        <InputText type="text" @bind-Value="Model.LastName" class="form-control" 
        name="LastName"/>
        <ValidationMessage For="@(() => Model.LastName)" />
    </div>

    <div class="col-md-3">
        <label for="Age" class="form-label">Age</label>
        <InputText type="text" @bind-Value="Model.Age" class="form-control" name="Age"/>
        <ValidationMessage For="@(() => Model.Age)" />
    </div>
    </EditForm>


    @code{
    [CascadingParameter]
    public MainModel MainModel { get; set; }

    private ChildModel Model {get; set; }


    private EditContext editContext;

    protected override async Task OnInitializedAsync()
    {
        editContext = new EditContext(Model);
        editContext.OnFieldChanged += EditContext_OnFieldChanged;
        base.OnInitialized();
    }

    private async void EditContext_OnFieldChanged(object sender, FieldChangedEventArgs e)
    {
        if(editContext.Validate()) //<-- this shows validation messages
        {
            //copy child model to main model here
        }
    }
}

問題是,一旦一個字段被修改,這個事件就會被觸發,正如預期的那樣,並且模型會被驗證,它會為所有輸入觸發驗證消息,因為此時沒有填寫任何其他必填字段。

有沒有辦法在不觸發驗證消息的情況下驗證模型?

也許我需要對 ValidationMessageStore 做一些事情,但我還沒有弄清楚。 我可以通過查看輸入兄弟的修改和無效類來切換單個驗證消息,但我確信 Blazor 有解決方案。

到目前為止,我還沒有答案,所以我目前的實現是這樣的:

當 EditContext.Validate() 被調用時,我最初用 css 隱藏消息,只有在輸入被修改和無效時才顯示它們:

.validation-message {
  display: none; 
}

input.modified.invalid {
  border: 1px solid red;
  position: relative; 
}

input.modified.invalid + .validation-message {
    position: absolute;
    margin-top: -10px;
    color: red;
    background: #fdf2f2;
    border: 1px solid #ffdede;
    padding: 5px;
    display: block;
    z-index: 1; 
}

我通常做的是有一個 bool 變量來捕獲 editContext 是否有效。 類似於prive bool _modelHasBeenModified {get; set;} = false; prive bool _modelHasBeenModified {get; set;} = false;

然后我將運行驗證_modelHasBeenModified = editContext.Validate();

然后我將重置驗證,以便不顯示任何驗證消息: editContext.MarkAsUnmodified(); - 這樣,我仍然可以保留_modelHasBeenModified的模型有效性。

不是直接的答案,但 Chris Sainty 為 FluentValidator @AliK 所指的創建了一個 blazor 包裝器。 他在他的書和博客中描述了非常優雅的解決方案。 比自己滾動要簡單得多。

  1. 添加他的Blazored Nuget 包

dotnet add package FluentValidation

  1. 在 EditForm 中插入他的組件,替換較弱的 DataAnnotationsValidator:

<FluentValidationValidator @ref="fluentValidationValidator" />

  1. 創建一個變量來保存驗證器引用:

private FluentValidationValidator fluentValidationValidator;

  1. 為您的子模型設置流暢的驗證 真正強大的工具已經存在了一段時間。 我已經能夠設置復雜的記錄級別驗證、重復檢查等。

  2. 現在您可以很容易地在代碼中進行驗證:

     var isValid = fluentValidationValidator.Validate(opts => opts.IncludeAllRuleSets()); if (!isValid) return; // show errors // else, proceed

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM