使用 Catel 和相当复杂的对象进行验证

Validation with Catel and quite complex object

我正在尝试以更智能的方式实施验证... 从一开始我就有一个 gridview,其中包含从数据库加载的一些数据(该对象不继承自 ModelBase)。当用户右键单击项目结束编辑时,会出现一个编辑弹出窗口。

这是加载弹出窗口的代码window

public override async Task UpdateDeal(IDeal deal)
    {
        var item = (DealForward)deal.Clone();
        var modello = viewModelFactory.CreateViewModel<DealForwardUpdateViewModel>(item);



        var dependencyResolver = this.GetDependencyResolver();
        var uiVisualizerService = dependencyResolver.Resolve<IUIVisualizerService>();

        await uiVisualizerService.ShowDialogAsync(modello);
    }

这是 DealForwardUpdateViewModel

public class DealForwardUpdateViewModel : DealUpdateViewModel
{
    #region Model
    [Model]
    public DealForwardUpdateModel Model
    {
        get { return GetValue<DealForwardUpdateModel>(DealForwardUpdateModelProperty); }
        set { SetValue(DealForwardUpdateModelProperty, value); }
    }
    public static readonly PropertyData DealForwardUpdateModelProperty = RegisterProperty("Model", typeof(DealForwardUpdateModel), null);
    #endregion

    #region Properties
    [ViewModelToModel("Model")]
    public DealForward Deal
    {
        get { return GetValue<DealForward>(DealProperty); }
        set { SetValue(DealProperty, value); }

    }

    public static readonly PropertyData DealProperty = RegisterProperty("Deal", typeof(DealForward), null);

    #endregion

    #region Ctor
    public DealForwardUpdateViewModel(DealForward forward, IDynamicContainer container)
    {
        this.Model = new DealForwardUpdateModel(forward);

        this.container = container;
    }

我不确定在 DealForwardUpdateModel 中放什么,我应该只放 DealForward 还是当我在构造函数中时必须将它分解到它自己的字段中?

public class DealForwardUpdateModel : ModelBase
{
    public double? Cambio { get; set; }

    public DealForwardUpdateModel(DealForward deal)
    {
        this.Deal = deal;
        this.Cambio = deal.Cambio;
    }
    public DealForward Deal
    {
        get { return GetValue<DealForward>(DealProperty); }
        set { SetValue(DealProperty, value); }
    }
    public static readonly PropertyData DealProperty = RegisterProperty("Deal", typeof(DealForward), null);
}

[ValidatorDescription("DealForwardUpdateModel", Catel.Data.ValidationResultType.Error, Catel.ValidationType.Field)]
public class DealForwardUpdateModelValidator : AbstractValidator<DealForwardUpdateModel>
{
    public DealForwardUpdateModelValidator()
    {
        RuleFor(x => x.Deal.Split).SetValidator(new SplitValidator());

        RuleFor(x => x.Cambio).GreaterThan(0).WithMessage(DealResources.STR_VALIDATION_CAMBIO);

        RuleFor(x => x.Deal.QtaDiv1).LessThan(0).When(x => x.Deal.Segno == 1).WithMessage(DealResources.STR_VALIDATION_NEGATIVE_QTA1);
        RuleFor(x => x.Deal.QtaDiv1).GreaterThanOrEqualTo(0).When(x => x.Deal.Segno == 0).WithMessage(DealResources.STR_VALIDATION_POSITIVE_QTA1);

        RuleFor(x => x.Deal.QtaDiv2).LessThan(0).When(x => x.Deal.QtaDiv1 > 0).WithMessage(DealResources.STR_VALIDATION_OPPOSITE_QTA2);
        RuleFor(x => x.Deal.QtaDiv2).GreaterThan(0).When(x => x.Deal.QtaDiv1 < 0).WithMessage(DealResources.STR_VALIDATION_OPPOSITE_QTA2);
    }
}

第二个选项似乎可行,但在将我的 DealForward 粉碎到字段列表之前,我询问是否有更好的方法。

请考虑我有 3/4 不同类型的交易,他们有一个可共享的 editable/validatable 部分

谢谢

您可以通过多种方式实施验证:

  1. Validar(Fody 插件),就像您在第二个示例中所做的那样
  2. FluentValidation(Catel 对此有扩展)
  3. 通过覆盖 ValidateFields 和 ValidateBusinessRules 在模型/视图模型中可用的简单验证

1 和 2 给出了一个不错的 SoC(关注点分离)。