2015-12-30 4 views
0

Я работаю над проектом с множеством сложных правил валидации. Мы используем Fluent Validation, чтобы помочь с этим и прекрасным инструментом. Однако наши модели часто имеют пары Nullable Datetimes, указывающие начало и конец чего-то. Текущая модель, над которой я работаю, имеет три разные пары, и я замечаю, что проверка несовместима, потому что каждый раз мы выписываем правила проверки для этой ситуации. Не сухим. Я ищу способ иметь общую пару методов для проверки пары дат с помощью Fluent Validation.Многоразовые методы сравнения двух нулевых дат с хорошей проверкой

До сих пор я нашел два подхода, но не очень подходит. Первый заключается в использовании пользовательского PropertyValidator, как описано ниже, но при использовании этого вы имеете доступ только к одному свойству. Я не могу найти способ передать оба времени и не могу пройти в родительской модели, потому что это будет использоваться на многих моделях (может что-то сделать с интерфейсом, но это много моделей для изменения ...). Fluent validation with dynamic message

Второй подход использует Must с перегрузкой предикатов, поэтому я могу проходить в оба своих времени. Это работает, но я не могу понять, как передавать какие-либо сообщения о том, какая ошибка возникает, она либо истинна, либо ложна. Это мой текущий код тестирования:

RuleFor(i => i.Start) 
      .Must((model,start) => BeValidDatePair(start, model.End)); 

public bool BeValidDatePair(DateTime? start, DateTime? end) 
    { 
     // Both values must be set or none 
     if (start.HasValue && !end.HasValue) 
     { 
      return false; 
     } 
     if (end.HasValue && !start.HasValue) 
     { 
      return false; 
     } 

     // End cannot exceed start by two years 
     if (end.Value > start.Value.AddYears(2)) 
     { 
      return false; 
     } 

     return true; 
    } 

В идеале, я бы две функции, один для даты начала и один для конца. В каждой функции я выполняю проверки и возвращаю, какая проверка не выполняется. Есть идеи?

// Ideal Case... 

public class MyModel 
{ 
    string Title { get; set; } 
    DateTime? Start { get; set; } 
    DateTime? End { get; set; } 
} 

RuleFor(i => i.Start) 
      .Must((model,start) => BeValidStartDate(start, model.End)); 

RuleFor(i => i.End) 
      .Must((model,end) => BeValidEndDate(end, model.Start)); 

public bool BeValidStartDate(DateTime? start, DateTime? end) 
{ 
     // start must come before end 
     if (start.Value < end.Value) 
     { 
      // psuedocode... 
      return ValidationMessage("Start must come before end."); 
     } 

     // other validations... 
} 

ответ

1

Вы можете добавить третий параметр, используя из модификатора и передать сообщение через что:

public bool BeValidDatePair(DateTime? start, DateTime? end, out string message) 
{ 
    ... 

    if (start.Value < end.Value) message = "Start must come before end."; 
} 

Тогда вы назвали бы это так:

string message = String.Empty; 
BeValidDatePair(dateone, datetwo, message); 

https://msdn.microsoft.com/en-us/library/t3c3bfhx.aspx


Другой вариант может быть, чтобы бросить свои собственные типы исключений и поймать их неявно с Try/уловом:

public class DateOutOfRangeException : Exception 
{ 
    ... 
} 

И:

catch (DateOutOfRangeException ex) 

Тогда:

if (start.Value < end.Value) throw new DateOutOfRangeException(); 

https://msdn.microsoft.com/en-us/library/87cdya3t(v=vs.110).aspx

Смежные вопросы