Writing a Custom Validator

Server-side implementation

A custom validator must inherit from ValidationAttribute. For client-side validation, it must also implement IWFClientValidatable.

Here is an example of a custom validator that checks if the value supplied is a number greater than 5 but less than 10 called "NumberCheck".

Be sure to omit implementation of IWFClientValidatable if the validator is not implemented on the client-side or a JavaScript error may occur.
public class NumberCheckAttribute : ValidationAttribute, IWFClientValidatable
{
   public override bool IsValid(object value)
   {
      //Check if the value is null or empty.
      //If so, return true since "NumberCheck" is not a "required field check"
      if(value == null || String.IsNullOrEmpty(value.ToString())) { return true; }
      int nValue = default(int);
      bool didParse = int.TryParse(value.ToString(), out nValue);
      //If we couldn't parse it into an integer, validation fails
      if(!didParse) { return false; }
      else {
         return nValue > 5 && nValue < 10;
      }
   }
   
   #region IWFClientValidatable Members
   
   public IEnumerable<WFModelClientValidationRule> GetClientValidationRules()
   {
      //Create a WFModelClientValidationRule
      //This will instruct the client-side code which
      //JavaScript validation rule to use and
      //what the error message should be.

      //If "numbercheck" has not been defined,
      //a JavaScript error will occur!
      var rule = new WFModelClientValidationRule {
         ErrorMessage = ErrorMessage,
         ValidationType = "numbercheck"
      };

      return new[] { rule };
   }

   #endregion
}

Client-side implementation

For client validation to work, a JavaScript validator must be added to jQuery validate. Documentation on jQuery validate is available here:
http://docs.jquery.com/Plugins/Validation
The "NumberCheck" validator example above would be implemented thusly:
jQuery.validator.addMethod("numbercheck", function(value, element, params) {
      //"params" are any parameters we could've specified 
      //earlier in the C# "GetClientValidationRules()" method
      //"element" is the target DOMElement
      //"value" is the current value being validated

      //Validation does not fail if it's empty...
      if(value === undefined || (value + '') === "") { return true; }

      //Return false if this isn't a number
      var isNumber = !isNaN(parseFloat(n)) && isFinite(n);
      if(!isNumber) { return false; }
      
      return value > 5 && value < 10;
   }
});

To apply this new validator to a model property, just decorate it with the attribute.
public class MyClass
{
      [NumberCheck]
      public int NumberProperty { get; set; }
}

Don't forget to enable client-side validation.
This can be done using the server control...
<WebFu:EnableClientValidation runat="server" />
...or the WFUtilities method ...
<%=WFUtilities.EnableClientValidation(Html.MetaData) %>

Configuring a custom validator using XML

Custom validators can be configured using WebFu's XML rules provider.
Public properties can be assigned by adding them as attributes to the <validator></validator> tag.
For example:
<validation>
   <type assemblyName="MyAssembly" name="MyAssembly.ClassName, MyAssembly">
      <ruleset name="MyRuleSet">
         <properties>
            <property name="MyProperty">
               <validator negated="false"
                                ErrorMessage="Custom validator error message."
                                type="MyAssembly.CustomValidatorType, MyAssembly"
                                CustomProperty1="CustomValue1"
                                CustomProperty2="CustomValue2"
                                ...... />
For more information on configuring validation via XML, see the WFXmlRuleSetProvider wiki page.

Last edited Jun 12, 2012 at 6:46 PM by aikeru, version 11

Comments

No comments yet.