2010-07-27 93 views
1

我有一个ViewModel封装了一个数据源,它是一个域对象。该域具有验证规则,这些规则在域中定义,但被ViewModel重用以向用户提供信息。流利的验证:我如何重用属性验证(投影)

视图模型:

internal class RatedValuesViewModel : FluentDataErrorInfo 
{ 
    public RatedValuesViewModel() 
     : base(new RatedValuesViewModelValidator()) 
    { 
    } 

    public RatedValues DataSource { get; set; } 

    ... 
} 

域对象:

class RatedValues 
{ 
    public double? Head 
    { 
     get; set; 
    } 

    public double? DeltaPressure 
    { 
     get; set; 
    } 

    ... 
} 

在操作的上下文中的域对象的规则,我们会进行:

class GeneratePlotPumpCurvesRatedValuesValidationRules : AbstractValidator<RatedValues> 
{ 
    public GeneratePlotPumpCurvesRatedValuesValidationRules() 
    { 
     Custom(itemToValidate => !AtLeastOneParameterSpecified(itemToValidate) ? new ValidationFailure(string.Empty, "You must specify at least one rated value.") : null); 

     RuleFor(item => item.Head).Must(head => head == null).When(item => item.DeltaPressure != null).WithMessage("You can not specify both head and delta pressure."); 
     RuleFor(item => item.DeltaPressure).Must(dp => dp == null).When(item => item.Head != null).WithMessage("You can not specify both head and delta pressure."); 
    } 

... 
} 

最后:视图模型的验证规则重用域中的验证规则:

class RatedValuesViewModelValidator : AbstractValidator<RatedValuesViewModel> 
{ 
    private readonly GeneratePlotPumpCurvesRatedValuesValidationRules _generatePlotPumpCurvesRatedValuesValidationRules = new GeneratePlotPumpCurvesRatedValuesValidationRules(); 

    public RatedValuesViewModelValidator() 
    { 
     RuleFor(viewModel => viewModel.DataSource).SetValidator(_generatePlotPumpCurvesRatedValuesValidationRules); 

     Custom(viewModel => 
        { 
         if (viewModel.DataSource == null) 
          return null; 

         ValidationResult validationResult = _generatePlotPumpCurvesRatedValuesValidationRules.Validate(viewModel.DataSource, viewModel.DataSource.GetPropertyName(vm => vm.Head)); 

         return !validationResult.IsValid ? new ValidationFailure(viewModel.GetPropertyName(vm => vm.Head), CombineErrors(validationResult.Errors)) : null; 
        }); 
    } 

    private static string CombineErrors(IEnumerable<ValidationFailure> errors) 
    { 
     StringBuilder combinedErrors = new StringBuilder(); 

     errors.ForEach(error => combinedErrors.AppendLine(error.ErrorMessage)); 

     return combinedErrors.ToString(); 
    } 
} 

在viewmodel的验证类中,我重用为属性“Head”定义的验证规则,并将它们公开为viewmodel属性“Head”的规则。正如你所看到的,对于我经常会做的事情,有相当多的代码。我可以使用任何流畅的验证框架功能来设置此“验证属性预测”吗?

回答

0

我没有找到任何方法在框架中做到这一点,但我已经创建了一个扩展方法,它使我能够做我想做的一行代码。

例子:

class PumpCurveViewModelValidationRules : AbstractValidator<PumpCurveViewModel> 
{ 
    readonly ConstantPumpCurveParametersValidationRules _constantParametersValidator = new ConstantPumpCurveParametersValidationRules(); 

    public PumpCurveViewModelValidationRules() 
    { 
     this.AddPropertyProjectionRule<PumpCurveViewModelValidationRules, PumpCurveViewModel, ConstantPumpParameters>(c => c.Speed, vm => vm.CurveSpeed, vm => vm.DataSource.ConstantPumpParameters, _constantParametersValidator);   
    } 
} 
+0

你有你如何得到这个在任何地方工作?会有兴趣。 – Schotime 2016-06-23 23:44:25

+0

你能告诉我们你创建的扩展方法吗? – 2018-01-15 16:23:16