我正在开发一个包含许多复杂验证规则的项目。我们正在使用Fluent验证来帮助解决这个问题,这是一个很棒的工具。但是,我们的模型通常有一对Nullable Datetimes,表示某事物的开始和结束。我正在处理的当前模型有三个不同的对,我注意到验证是不一致的,因为我们每次都在为这种情况写出验证规则。至少不干。我正在寻找一种通过Fluent验证来验证一对日期时间的方法。
到目前为止,我找到了两种方法,但两种方法都不合适。第一种是使用如下所述的自定义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...
}
答案 0 :(得分:1)
您可以使用out修饰符添加第三个参数,并通过以下内容传递消息:
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 / catch隐式捕获它们:
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