2010-04-01 117 views
8

使用FluentValidation,是否可以验证string为可解析DateTime而无需指定Custom()委托?如何使用FluentValidation验证字符串为DateTime

理想情况下,我想这样说的EmailAddress的功能,如:

RuleFor(s => s.EmailAddress).EmailAddress().WithMessage("Invalid email address"); 

因此,像这样:

RuleFor(s => s.DepartureDateTime).DateTime().WithMessage("Invalid date/time"); 

回答

21
RuleFor(s => s.DepartureDateTime) 
    .Must(BeAValidDate) 
    .WithMessage("Invalid date/time"); 

和:

private bool BeAValidDate(string value) 
{ 
    DateTime date; 
    return DateTime.TryParse(value, out date); 
} 

或者你可以写一个custom extension method

+0

这是真棒,但它不会产生正确的HTML5验证和页面提交后才会生效,有没有什么办法让库生成对应的html5? – 2014-06-16 08:26:00

1

如果s.DepartureDateTime已经是一个DateTime财产;验证它为DateTime是无稽之谈。 但是,如果它是一个字符串,Darin的答案是最好的。

要添加的另一件事, 假设您需要将BeAValidDate()方法移动到外部静态类,以便不在每个地方重复相同的方法。如果你选择这样做,你需要修改Darin的规则:

RuleFor(s => s.DepartureDateTime) 
    .Must(d => BeAValidDate(d)) 
    .WithMessage("Invalid date/time"); 
2

你可以用完全相同的方式完成EmailAddress。

http://fluentvalidation.codeplex.com/wikipage?title=Custom

public class DateTimeValidator<T> : PropertyValidator 
{ 
    public DateTimeValidator() : base("The value provided is not a valid date") { } 

    protected override bool IsValid(PropertyValidatorContext context) 
    { 
     if (context.PropertyValue == null) return true; 

     if (context.PropertyValue as string == null) return false; 

     DateTime buffer; 
     return DateTime.TryParse(context.PropertyValue as string, out buffer); 
    } 
} 

public static class StaticDateTimeValidator 
{ 
    public static IRuleBuilderOptions<T, TProperty> IsValidDateTime<T, TProperty>(this IRuleBuilder<T, TProperty> ruleBuilder) 
    { 
     return ruleBuilder.SetValidator(new DateTimeValidator<TProperty>()); 
    } 
} 

然后

public class PersonValidator : AbstractValidator<IPerson> 
{ 
    /// <summary> 
    /// Initializes a new instance of the <see cref="PersonValidator"/> class. 
    /// </summary> 
    public PersonValidator() 
    { 
     RuleFor(person => person.DateOfBirth).IsValidDateTime(); 

    } 
}