簡體   English   中英

觸發相關屬性的驗證 (FluentValidation)

[英]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.

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