[英]Trigger Validation of a related property (FluentValidation)
我在一個類中有兩個相互依賴的屬性:
public class SomeClass
{
public DateTime EarliestDeliveryDate { get; set; }
public DateTime LatestDeliveryDate { get; set; }
...
}
我將 FluentValidation 配置如下:
using FluentValidation;
...
public class SomeValidator : AbstractValidator<SomeClass>
{
public SomeValidator ()
{
RuleFor(x => x.EarliestDeliveryDate).Must((order, earliestDeliveryDate) => earliestDeliveryDate < order.LatestDeliveryDate)
.WithMessage("Earliest delivery date has to be before the latest delivery date.");
RuleFor(x => x.LatestDeliveryDate)
.Must((order, latestDeliveryDate) => latestDeliveryDate > order.EarliestDeliveryDate)
.WithMessage("Latest delivery date has to be after the earliest delivery date.");
...
}
}
每個屬性的驗證都按預期工作。 但是,如果用戶為這兩個屬性輸入了無效日期,然后更正了其中一個輸入字段(比如 EarliestDeliveryDate),則另一個屬性的錯誤消息(例如 LatexDeliveryDate)仍然存在。
如果一個屬性的值發生變化,如何觸發所有依賴屬性的驗證?
DateTime
結構的默認值是公元 1 月 1 日。也許用戶界面中的無效日期被回發,然后被忽略,因此改用 DateTime 的默認值。
要解決此問題,您需要通過放置一個?
屬性類型名稱后的字符: DateTime?
public class SomeClass
{
public DateTime? EarliestDeliveryDate { get; set; }
public DateTime? LatestDeliveryDate { get; set; }
...
}
那么無效日期將為null
,更糟糕的情況。 如果兩個日期都包含 DateTime 對象,則您只想比較兩個日期:
// If both fields are required:
RuleFor(x => x.EarliestDeliveryDate)
.NotEmpty();
RuleFor(x => x.LatestDeliveryDate)
.NotEmpty();
When(order => order.EarliestDeliveryDate.HasValue && order.LatestDeliveryDate.HasValue, () =>
{
RuleFor(x => x.EarliestDeliveryDate)
.Must((order, earliestDeliveryDate) => earliestDeliveryDate < order.LatestDeliveryDate)
.WithMessage("Earliest delivery date has to be before the latest delivery date.");
RuleFor(x => x.LatestDeliveryDate)
.Must((order, latestDeliveryDate) => latestDeliveryDate > order.EarliestDeliveryDate)
.WithMessage("Latest delivery date has to be after the earliest delivery date.");
});
我的建議是讓您的模型類實現INotifyPropertyChanged
接口,然后在所有相關屬性的 Setter 中引發事件,如下所示:
public int LocationId
{
get => locationId;
set
{
locationId = value;
NotifyPropertyChanged(nameof(LocationId));
if (HazardId != default && MeasuredPersianDate != default)
{
NotifyPropertyChanged(nameof(HazardId));
NotifyPropertyChanged(nameof(MeasuredPersianDate));
}
}
}
這樣,如果您的 UI 是像 WPF 或 Xamarin Forms 這樣的框架,隨着相關屬性之一發生變化,其他屬性也會自動觸發驗證。但是,如果您的 UI 框架在以下情況下沒有自動刷新視圖引發了NotifyPropertyChanged
,您需要訂閱該事件並讓 UI 觸發相關屬性的驗證。例如,在 Blazor 中,您可以使用以下代碼:
model.PropertyChanged +=
(object sender, System.ComponentModel.PropertyChangedEventArgs e) =>
{
if (e.PropertyName is null) return;
form.EditContext!.NotifyFieldChanged(form.EditContext.Field(e.PropertyName));
};
其中form
是使用@ref
引用EditForm的變量
<EditForm @ref="form" Context="ctx" Model="model"OnValidSubmit="SaveChanges">...</EditForm>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.