Base validation with configuration bug ?

Topics: Validation Application Block
Apr 18, 2007 at 8:53 PM
Hi,
I did test the VAB and found out that in my simple setup the validators defined on a base class or an abstract class only work when defined as attributes in code. When configuring the same validators in the configuration consule, the validators are not called. Is this a bug, or is my implementation wrong?

I've tried following options:
- ValidationResults lResults = Validation.Validate(lPerson);
- ValidationResults lResults = Validation.Validate<Person>(lPerson);
- Validator v = ValidationFactory.CreateValidator(lPerson.GetType());

Same results for the winforms ValidatorProvider by the way.

Greetz
BtV
Apr 25, 2007 at 11:27 AM
Anyone ????
Apr 25, 2007 at 2:56 PM
I got it to work with interfaces using configuration with no problems.

namespace Interfaces
{
    public interface IPerson
    {
        string Name { get; set; }
    }
}

namespace Interfaces
{
    public class Person : IPerson
    {
        #region IPerson Members
 
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
 
        #endregion
    }
}

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="validation" type="Microsoft.Practices.EnterpriseLibrary.Validation.Configuration.ValidationSettings, Microsoft.Practices.EnterpriseLibrary.Validation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </configSections>
    <validation>
        <type defaultRuleset="Default" assemblyName="Interfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
            name="Interfaces.IPerson">
            <ruleset name="Default">
                <properties>
                    <property name="Name">
                        <validator negated="false" messageTemplate="" messageTemplateResourceName=""
                            messageTemplateResourceType="" tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                            name="Not Null Validator" />
                    </property>
                </properties>
            </ruleset>
        </type>
    </validation>
</configuration>

using System;
using Microsoft.Practices.EnterpriseLibrary.Validation;
 
namespace Interfaces
{
    class Program
    {
        static void Main(string[] args)
        {
            IPerson person = new Person();
            ValidationResults results = Validation.Validate(person);
            if (!results.IsValid)
            {
                foreach (ValidationResult result in results)
                {
                    Console.WriteLine("Key:{0}, Message:{1}", result.Key, result.Message);
                }
 
                Console.ReadLine();
            }
        }
    }
}
 

When I run the application above, it tells me the name cannot be null which is exactly what it should be doing. I recommend checking the quickstarts or using the example above as a guide.

Regards,

Dave

______________________________

David Hayden
Microsoft MVP C#
Apr 25, 2007 at 4:02 PM
David,
what I meant to do was validate the derived Person that implements the BasePerson abstract class.

If I validate the base class, it validates the rules defined in configuration and attributes on the abstract class
BasePerson lPerson = new Person(txtFirstName.Text, txtLastName.Text);
ValidationResults lResults = Validation.Validate(_Person);

If I validate the derived class, it validates the rules defined in configuration and attributes on the Person class and only the rules defined in attributes on the abstract class
Person lPerson = new Person(txtFirstName.Text, txtLastName.Text);
ValidationResults lResults = Validation.Validate(_Person);

So my problem is that when validating a derived class, the validation rules defined for the abstract class in configuration are ignored.
My UI should not know what classes the Person class derived from.

Can you confirm this ?

Greetz
BtV

Ps. an earlier thread (answered by Tom) confirmed me that interfaces are totally ignored (config + attributes) when validating the derived class
http://www.codeplex.com/entlib/Thread/View.aspx?ThreadId=9227
Apr 27, 2007 at 2:49 PM
Yes, I confirmed the problem. The validation rules for the abstract class defined in configuration are ignored, but it does pick up the validation rules on the abstract class defined as attributes.

Looks like a bug to me. I would add it to the IssueTracker.


I was able to duplicate it with the following code:

    abstract public class Person
    {
        #region IPerson Members
 
        private string _name;
 
        // NotNullValidator in Configuration File
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
 
        private int _age;
 
        [RangeValidator(1, RangeBoundaryType.Inclusive,
                        100, RangeBoundaryType.Inclusive)]
        public int Age
        {
            get { return _age; }
            set { _age = value; }
        }
 
        #endregion
    }

    public class Driver : Person
    {
        private string _license;
 
        [NotNullValidator]
        public string License
        {
            get { return _license; }
            set { _license = value; }
        }
    }

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="validation" type="Microsoft.Practices.EnterpriseLibrary.Validation.Configuration.ValidationSettings, Microsoft.Practices.EnterpriseLibrary.Validation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  </configSections>
  <validation>
    <type defaultRuleset="Default" assemblyName="Interfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
      name="Interfaces.Person">
      <ruleset name="Default">
        <properties>
          <property name="Name">
            <validator negated="false" messageTemplate="" messageTemplateResourceName=""
              messageTemplateResourceType="" tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
              name="Not Null Validator" />
          </property>
        </properties>
      </ruleset>
    </type>
  </validation>
</configuration>


This code does not take into consideration the validation of the Person's Name Property that is defined in the configuration file:

            Driver driver = new Driver();
            ValidationResults results = Validation.Validate(driver);
            if (!results.IsValid)
            {
                foreach (ValidationResult result in results)
                {
                    Console.WriteLine("Key:{0}, Message:{1}", result.Key, result.Message);
                }
 
                Console.ReadLine();
            }


Regards,

Dave

_____________________________

David Hayden
Microsoft MVP C#