Tom Hollander's blog

patterns, practices and pontification

Validators supplied in the VAB

Validators supplied in the VAB

  • Comments 35

We're making great progress with the Validation Application Block in Enterprise Library 3.0, and one of the last remaining tasks is to make sure we include a compelling set of validators with the block. While it's very easy to build your own validator, we don't want everyone to need to build the same validators for each project just because we forgot to include something important.

Here's the set of validators we're currently planning to include - but it's not too late to set us straight if we've missed something! A few things to note are:

  • All of these validators can be used from the API, attributes or configuration, although the syntax will vary across these mechansims.
  • Some of the validators will use generic parameters, such as RangeValidator<T>. When used from the API, you will be able to use the validator with any type (subject to the generic parameter's constraints). However since you can't use generics in the same way from configuration or attributes, you'll only be able to use common primitive types from these mechanisms.
  • All of our validators will include a Negate property, which will change the validator's behavior so that it will fail if the condition is met, rather than when it is not met. This will let you do things like use the "Contains Characters Validator" to check that a string does not contain characters.

First, here are the planned "basic" validators:

  • Not Null Validator: Validates that a value is not null
  • Range Vailidator (generic, supporting IComparable types): Validates that a value falls within a specified range. The range may be closed or open ended, and may be inclusive or exclusive.
  • Relative DateTime Validator: Validates that a DateTime falls within a specified range, relative to now. The range may be closed or open ended, and may be inclusive or exclusive. For example, you could check if a date is between now and 100 years from now, or from 20 days ago to 4 days from now.
  • String Length Validator: Validates that a string is of a certain length. May contain a minimum, a maximum or both.
  • RegEx Validator: Validates that a string matches a specified regular expression. We'll also include support for "pre-canned" RegEx patterns for common things such as URLs, e-mail addresses, phone numbers etc.
  • Contains Characters Validator: Validates that a string contains any, or all of the characters in a specified string.
  • Type Conversion Validator: Validates that a string can be converted to a specific type (using a specific culture). For example, this could check that "6.32" can be converted to a Double, or "2007-02-09" can be converted to a DateTime.
  • Enum Conversion Validator: Validates that a string can be converted to a value in a specified enum type. For example, this could check that "Blue" could be converted to a value in the Color enum.
  • Domain Validator (generic): Validates that a value is included in a specified set, such as {"John", "Paul", "George", "Ringo"} or {2, 3, 5, 7, 11}. If the set only contains one value, this validator can be used to check for equality.

Next, here are our planned "composition" validators:

  • And Composite Validator: Indicates that all of a set of child validators must pass
  • Or Composite Validator: Indicates that just one of a set of child validators must pass.

Finally, here are our planned "value access" validators, which can be used to specify validation rules on complex objects:

  • Property: Applies a validator to a property of an object
  • Field: Applies a validator to a field of an object
  • Method: Applies a validator to the result of a method of an object (can only be used for methods with no parameters and a non-void result, such as ToString()).
  • Object: Specifies that a nested object needs to be validated by a particular rule set.
  • Collection: Specifies that a nested collection of objects needs to be validated by a particular rule set.

Did we miss anything important?

  • Is there just a standard ComparisionValidator where you can say like 'greater than -1'.

  • Kristian - you can do this with the RangeValidator (by only specifying one boundary).

  • In addition to the And Validator and the Or Validator, what about something in-between (I don't have a good name now) which can validate that at least X conditions in the set are met.

    So, if you have 5 validators, and you want to be sure at least 3 of 5 are met (perhaps this is "good enough" quality for data input).

    Between those three, and the "Negate" property you mentioned, it should be possibly to express fairly complex validation when needed.

  • How about a support for contexts,

    i.e. I have a user class and this user can actually be multiple types of user (standard, power, ultimate).

    I'd like the ability to specify validate for a given context e.g. ValidationMananger.Validate(User, Context) [please not I have not used any part of the block and the example is simply that]. So a bit like composite validator but you don't need to know which rules will fire....just that given the current context the right ones will fire.

    I'm sure there are other ways you could get around it....but just a suggestion.

  • John - actually we already support this, through the concept of "rulesets" which are named collections of validators. The syntax is almost the same as what you specified:

    ValidationResults results = Validation.Validate(myUser, "Power");

  • To be robust it should match the feature set of Peter Blum's validation package for ASP.Net. Multi-condition, centralized message panel to name a few.

  • What about a CompareValidator that can reference another Field/Property/Method/etc... not to compare to a literal, but (for example) to compare two password entries.

  • This is small thing, but you may consider this: DoesFileExist(filepath) and DoesFileNotExist.

    first check that the file path is not nothing and not empty then check the existence of the file (File.Exist).

  • I agree with IDisposable... It would be nice to have an out-of-the-box validator that knows how to compare two properties, for cases like start/end date input, repeat password, etc.

  • Two points:

    1) Unless I'm missing something the proposed architecture can't handle co-occurance constraints (e.g. "If Customer.OccupationType = 'Employed' Then Customer.Occupation.Address is required").

    2) I'm not sure I want my validation logic in code in the first place.  It seems like the better place for this is in a rules engine which your entities can call out to validate themselves.  Validation rules change.  They change often enough that I'd rather re-publish a rules update then re-compiling/deploying code.  Finally, a rules engine has no problem with point 1) above.

  • Quote

    To be robust it should match the feature set of Peter Blum's validation package for ASP.Net.

    end quote

    If not this, this validation should offer one-to-one mapping to asp.net validation controls. So that I can programmaticaly inject this validation controls counterpart asp.net control to my page easily. If I can do that, I will have best of both worlds. Defense in depth. My services will be validated also my client will have javascript support.

  • Tom,

    How about handling semi-mandatory data based on certain other input value conditions?

    -Ravi

  • What about Parameter validation. Often when you write methods you want to do simple checks to ensure that the values passed in are correct or in a certain range. It would be awesome to be able to drop for example a [NotNullValidator] a parameter to a method rather than having to manually code the checks. Another place this could be used is in a class constructor.

  • I totally agree with Glenn's comment about Parameter Validation; that would be one of the biggest benefits in my mind. If you could write;

    public void GetSomething(

      [NotNullValidator] string myName,

      [RangeValidator<int>(1, 100) int myAge)

    ... the boiler-plate code at the start of each method would be so much simpler, and code requirements and intentions would be more obvious from method definitions.

  • The Parameter Validation sounds like a great idea! But I'd want it for my methods, so I could write something like this:

    ...

    [Validate:NotNullOrEmptyString(boo), NotNull(hoo)]

    public int Foo(string boo, FooBoo hoo) {

    ...

Page 1 of 3 (35 items) 123