FluentValidation 3.1 available

FluentValidation 3.1 is now available for downloaded either from the CodePlex page or through NuGet.

The biggest new feature of 3.1 is being able to share a condition across multiple rules. In previous versions, if you wanted to re-use a condition across multiple rules then you’d have to declare the condition multiple times:

public class PersonValidator : AbstractValidator<Person> {
    public PersonValidator() {
        RuleFor(x => x.Surname).NotNull().When(x => x.Id > 0);
        RuleFor(x => x.Forename).NotNull().When(x => x.Id > 0);
    }
}

…but with 3.1 you can declare the condition once using a nested closure:

public class PersonValidator : AbstractValidator<Person> {
    public PersonValidator() {
        When(x => x.Id > 0, () => {
           RuleFor(x => x.Surname).NotNull();
           RuleFor(x => x.Forename).NotNull();
        });
    }
}

In addition, FluentValidation’s support for nullable types (which was enhancd with 3.0) has been extended to work with cross-property rules.

FluentValidation v3 available

FluentValidation v3 is now available for download. You can grab the binaries from the CodePlex page or by installing it using NuGet:

install-package FluentValidation

If you want integration with ASP.NET MVC 3, you can install the FluentValidation.Mvc3 nuget package:

install-package FluentValidation.Mvc3

For a summary of what’s new in this release, check out the following posts:

…or take a look at the full changelog.

Note that this release takes a dependency on .NET 4, so if you’re still running on .NET 3.5 then you’ll need to stick with FluentValidation 2.0.

FluentValidation v3: Other features

This is part 6 in a series of posts about the new features in FluentValidation v3.

In addition to the major new features I’ve already posted about, there are several other smaller features available in FluentValidation v3:

Support for DisplayAttribute

FluentValidation will now automatically infer the display name for properties annotated with the DisplayAttribute/DisplayNameAttribute.

Support for custom arguments in WithLocalizedMessage

Localized error messages now support custom format arguments in the same way as non-localized messages.

Support for validating child properties at the top level

FluentValidation v3 allows rules to be defined for child properties within the top level validator:

RuleFor(x => x.Address.PostalCode).NotNull();

In previous versions of FluentValidation, the property name would always be generated as “PostalCode” instead of “Address.PostalCode”, and you’d have to rely on a child validator which in some situations isn’t desirable.

Additional rules specified on the client

Support for client side error messages has been slightly expanded. The following rules are now supported on the client:

  • NotNull/NotEmpty
  • Matches (regex)
  • InclusiveBetween (range)
  • CreditCard
  • Email
  • EqualTo (cross-property equality comparison)
  • Length

In addition, the client-side error messages for several validators have been improved so they no longer rely on FluentValidation’s named placeholders when running on the client.

Specify a ruleset used to generate client-side rules

If you’re using rulesets alongside ASP.NET MVC, then you’ll notice that by default FluentValidation will only generate client-side error messages for rules not part of any ruleset. You can instead specify that FluentValidation should generate clientside rules from a particular ruleset by attributing your controller action with a RuleSetForClientSideMessagesAttribute:

[RuleSetForClientSideMessages("MyRuleset")]
public ActionResult Index() {
   return View(new PersonViewModel());
}

…plus several bug fixes.

FluentValidation v3: Conditional validation of collection elements

This is part 5 in a series of posts about new features in FluentValidation v3.

FluentValidation has supported validation of collection properties since v1.1. By using a child validator, you can indicate that each element in a collection should be validated:

public class Person {
  public List<Order> Orders { get; set; }
}
 
public class Order {
  public decimal? Amount { get; set; }
}
 
public class OrderValidator : AbstractValidator<Order> {
  public OrderValidator() {
     RuleFor(x => x.Amount).GreaterThan(0);
  }
}
 
public class PersonValidator : AbstractValidator<Person> {
  public PersonValidator() {
    RuleFor(x => x.Orders).SetValidator(new OrderValidator());
  }
}

With FluentValidation v3, you can now apply a condition to collection validators to indicate only certain items in the collection should be validated. To achieve this, FluentValidation v3 has a new “SetCollectionValidator” method which exposes an additional “Where” method in the fluent interface. It was necessary to introduce this extra method to differentiate SetValidator calls that are setting a child validator for the entire property from those that are validating collection elements.

Using the new feature, we could now only validate those Orders whose Amount is not null:

public class PersonValidator : AbstractValidator<Person> {
  public PersonValidator() {
    RuleFor(x => x.Orders).SetCollectionValidator(new OrderValidator())
        .Where(x => x.Amount != null);
  }
}

FluentValidation v3: Better handling of Nullable Types

This is part 4 in a post about new features in FluentValidation v3.

In previous versions of FluentValidation, if you wanted to use any of the comparison validators (GreaterThan, LessThan etc) against a nullable type you had to validate the nullable’s Value property in combination with a null check:

RuleFor(x => x.NullableInt.Value).GreaterThan(0).When(x => x.NullableInt != null);

This was necessary because the comparison validators require that the property implement IComparable (which Nullable<T> does not implement). Although this worked, it was somewhat cumbersome and unnecessarily verbose.

With FluentValidation v3, there are additional overloads for all of the comparison validators that work directly with nullables, so the above can be simplifed to:

RuleFor(x => x.NullableInt).GreaterThan(0);