Validation not being run.

Topics: Validation Application Block
Mar 1, 2007 at 9:00 PM
I have implemented a custom validator on my 'Account' object but when I run my unit test the validation is not being hit. Here is the code. Thanks for any assistance.

//Validator code:
using Microsoft.Practices.EnterpriseLibrary.Validation;
using NUnit.Framework;
 
namespace ClassLibrary1
{
    public class Account
    {
        public Account()
        {}
    }
 
    public class AccountValidator: Validator<Account>
    {
        /// <summary>
        /// Validates the Account object
        /// </summary>
        /// <param name="account"></param>
        /// <param name="messageTemplate"></param>
        public AccountValidator(Account account, string messageTemplate) : base(messageTemplate, null)
        {  
        }
 
 
        /// <summary>
        /// Validates An Account
        protected override void DoValidate(Account account,
            object currentTarget,
            string key,
            ValidationResults validationResults)
        {
            LogValidationResult(validationResults, MessageTemplate, currentTarget, key);
        }
 
        /// <summary>
        /// Gets or sets the message template to use when logging results.
        /// </summary>
        protected override string DefaultMessageTemplate
        {
            get { return "Error Message"; }
        }
 
    }
    [TestFixture]
    public class Tests
    {
        [Test]
        public void ValidateTest()
        {
            Account account = new Account();
            Validator<Account> validator = ValidationFactory.CreateValidator<Account>();
            ValidationResults results = validator.Validate(account);
            Assert.IsFalse(results.IsValid);
 
        } 
    }
 
}

//App.config

<?xml version="1.0"?>
<configuration>
	<configSections>
		<section name="validation" type="Microsoft.Practices.EnterpriseLibrary.Validation.Configuration.ValidationSettings, Microsoft.Practices.EnterpriseLibrary.Validation, Version=2.9.9.2, Culture=neutral, PublicKeyToken=null" />
	</configSections>
	<validation>
		<type assemblyName="ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
		  name="ClassLibrary1.Account">
			<ruleset name="Account">
				<validator messageTemplate="" messageTemplateResourceName=""
				  messageTemplateResourceType="" tag="" type="ClassLibrary1.AccountValidator"
				  name="Account Validator" />
			</ruleset>
		</type>
	</validation>
</configuration>
Mar 1, 2007 at 9:46 PM
Hi Steve -

The issue is that you have configured a ruleset called "Account", but your test code is asking for the default or anonymous ruleset. To make the validation fire, you can either:

1. Designate the "Account" ruleset as the default for the type in configuration:
<type defaultRuleset="Account" ...
2. Update the code to ask for the named ruleset:
Validator<Account> validator = ValidationFactory.CreateValidator<Account>("Account");

HTH
Tom
Mar 1, 2007 at 9:52 PM
Thanks Tom.

After trying both of the above. I now get the following error.

System.ArgumentException: The type 'ClassLibrary1.AccountValidator' cannot be resolved. Please verify the spelling is correct or that the full type name is provided.

thanks again.
Mar 1, 2007 at 10:03 PM
You need to use an assembly-qualified type in the <validator> element.
Mar 1, 2007 at 10:14 PM
Can you add an example of what that would look like in this case?

Mar 1, 2007 at 11:28 PM
"ClassLibrary1.AccountValidator, ClassLibrary1", assuming a non-strong-named assembly called ClassLibrary1.dll.
Add PublicKeyToken, Version and Culture where necessary.
Mar 2, 2007 at 1:16 AM
Edited Mar 2, 2007 at 1:17 AM
Steve,

I got it working with a few changes. Hopefully this helps:

namespace ClassLibrary1
{
    public class Account
    {
        public Account()
        { }
    }
 
    [ConfigurationElementType(typeof(CustomValidatorData))]
    public class AccountValidator : Validator<Account>
    {
        public AccountValidator(NameValueCollection attributes) : base(null, null)
        {
        }
 
 
        /// <summary>
        /// Validates An Account
        protected override void DoValidate(Account account,
            object currentTarget,
            string key,
            ValidationResults validationResults)
        {
            LogValidationResult(validationResults, MessageTemplate, currentTarget, key);
        }
 
        /// <summary>
        /// Gets or sets the message template to use when logging results.
        /// </summary>
        protected override string DefaultMessageTemplate
        {
            get { return "Error Message"; }
        }
 
    }
 
    [TestFixture]
    public class Tests
    {
        [Test]
        public void ValidateTest()
        {
            Account account = new Account();
            Validator<Account> validator = ValidationFactory.CreateValidator<Account>();
            ValidationResults results = validator.Validate(account);
            Assert.IsFalse(results.IsValid);
 
        }
    }
 
}

App.Config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="validation" type="Microsoft.Practices.EnterpriseLibrary.Validation.Configuration.ValidationSettings, Microsoft.Practices.EnterpriseLibrary.Validation, Version=2.9.9.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  </configSections>
  <validation>
    <type defaultRuleset="default" assemblyName="AccountValidator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
      name="ClassLibrary1.Account">
      <ruleset name="default">
        <validator messageTemplate="" messageTemplateResourceName=""
          messageTemplateResourceType="" tag="" type="ClassLibrary1.AccountValidator, ClassLibrary1"
          name="Custom Validator" />
      </ruleset>
    </type>
  </validation>
</configuration>


Regards,

Dave

______________________

David Hayden
Microsoft MVP C#
Mar 2, 2007 at 11:55 PM
This is awesome. Thank you!