[英]How to properly manipulate validation messages in EditContext with Blazor server
[英]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 包裝器。 他在他的書和博客中描述了非常優雅的解決方案。 比自己滾動要簡單得多。
dotnet add package FluentValidation
<FluentValidationValidator @ref="fluentValidationValidator" />
private FluentValidationValidator fluentValidationValidator;
為您的子模型設置流暢的驗證。 真正強大的工具已經存在了一段時間。 我已經能夠設置復雜的記錄級別驗證、重復檢查等。
現在您可以很容易地在代碼中進行驗證:
var isValid = fluentValidationValidator.Validate(opts => opts.IncludeAllRuleSets()); if (!isValid) return; // show errors // else, proceed
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.