FileConfigurationSource usage Question

Topics: Validation Application Block
Apr 4, 2007 at 12:02 AM
Hi,

I am working on a Class Library that would be using various application blocks like Data, Validation, Exception Handling, Logging etc.

The problem which I noticed while I was developing along with my Dev team is that it is hard to share the same App.Config file with multiple developers. So, we thought it would be convenient if we could break down the sole configuration file into mutliple files which is specific to each Application Block.

So, first I tried to break down the Validation application config settings to a seperate file called as "Validation.config".

With this setup I call the following method to do validation.
private static ValidationResults Validate<T>(T instance, String ruleSet)
{
FileConfigurationSource dataSource = new FileConfigurationSource(@"Validation.config");
Validator<T> validator = ValidationFactory.CreateValidator<T>(ruleSet, dataSource);
ValidationResults results = validator.Validate(instance);
return results;
}

But the problem is when I use ObjectCollectionValidator. The Collection property on which I apply this validator does not actually do the validation on individual entities within the collection. But the same validation works successfully, if I have all the configuration settings in the primary App.config file.


For e.g. consider the following classes:

public class Customer
{
private string _emailAddress;
private Address _address;
private Collection<Address> _addresses = new Collection<Address>();

public string EmailAddress
{
get { return _emailAddress; }
set { _emailAddress = value; }
}

public Collection<Address> Addresses
{
get { return _addresses; }
set { _addresses = value; }
}
}

public class Address
{
private string _zipCode;

public string ZipCode
{
get { return _zipCode; }
set { _zipCode = value; }
}
}

Now when I call validation on Customer using the following code, the ValidationResults does not include the validation results from the Address Collection.

String customerRuleSet = "Customer Ruleset";

Address address = new Address();

// Invalid Length
address.ZipCode = "123456789123456789";


Address address2 = new Address();
// Invalid Length
address2.ZipCode = "123456789123456789";

Customer customer = new Customer();
// Invalid Length
customer.EmailAddress = "";

customer.Addresses.Add(address);
customer.Addresses.Add(address2);

ValidationResults results = Validate(customer, customerRuleSet);

The following is what I have in the App.Config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
....
</appSettings>
</configuration>

The following is what I have in the Validation.Config file:

<?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 assemblyName="ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
name="ConsoleApplication1.ObjectValidation.Customer">
<ruleset name="Customer Ruleset">
....
</ruleset>
</type>
<type assemblyName="ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
name="ConsoleApplication1.ObjectValidation.Address">
<ruleset name="Address Ruleset">
....
</ruleset>
</type>
</validation>
</configuration>


My questions are:
1. What is the correct use of FileConfigurationSource. Am I using it for the right purpose here?
2. How do I correct this problem which I am facing where ObjectCollectionValidator does not work with FileConfigurationSource?
3. If I use FileConfigurationSource to do validation, will SelfValidation work. What are the pros and cons in using FileConfigurationSource?

Thanks a lot for reading! :)
Apr 5, 2007 at 2:01 AM
I am not sure of your problem because there is not enough information in the post, but I verified that FileConfigurationSource works fine with the ObjectCollectionValidator, etc.

The blocks don't care whether you use FileConfigurationSource to specify configuration from an external configuration file or use app.config or web.config. The location of the configuration does not affect block features.

Here is my example which is complete and works fine:

namespace ObjectValidatorConfig
{
    public class Customer
    {
        private string _emailAddress;
        private List<Address> _addresses;
 
        public string EmailAddress
        {
            get { return _emailAddress; }
            set { _emailAddress = value; }
        }
 
        public List<Address> Addresses
        {
            get { return _addresses; }
            set { _addresses = value; }
        }
    }
 
    public class Address
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            IConfigurationSource source = new FileConfigurationSource("Validation.config");
 
            Customer customer = new Customer();
            List<Address> addresses = new List<Address>();
            addresses.Add(new Address());
            addresses.Add(new Address());
            addresses.Add(new Address());
 
            customer.Addresses = addresses;
 
            Validator<Customer> validator = ValidationFactory.CreateValidator<Customer>(source);
            ValidationResults results = validator.Validate(customer);
        }
    }

Validation.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="ObjectValidatorConfig, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
		  name="ObjectValidatorConfig.Customer">
			<ruleset name="Default">
				<properties>
					<property name="EmailAddress">
						<validator negated="false" messageTemplate="" messageTemplateResourceName=""
						  messageTemplateResourceType="" tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=2.9.9.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
						  name="Not Null Validator" />
					</property>
					<property name="Addresses">
						<validator targetType="ObjectValidatorConfig.Address, ObjectValidatorConfig, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
						  targetRuleset="Default" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.ObjectCollectionValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=2.9.9.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
						  name="Object Collection Validator" />
					</property>
				</properties>
			</ruleset>
		</type>
		<type defaultRuleset="Default" assemblyName="ObjectValidatorConfig, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
		  name="ObjectValidatorConfig.Address">
			<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=2.9.9.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
						  name="Not Null Validator" />
					</property>
				</properties>
			</ruleset>
		</type>
	</validation>
</configuration>
 

Regards,

Dave

_________________________

David Hayden
Microsoft MVP C#
Aug 12, 2008 at 8:04 PM
Hi David,

I'm having the same problem as jubilanttiger. I tried your code. It doesn't work for me. I get one ValidationResult returned for the email address and nothing for the addresss collection.

If the ObjectCollectionValidator were working, I would get 4 ValidationResult objects in the ValidationResults. One for the email and three for the address collection (one for each of the addresses).

I suspect that the problem is actually in the configuration block.

Also, you appear to be using version  2.9.9.2 of entlib. I'm using 3.1.0.0. I'm not sure if that's the difference or not.

John
Mar 10, 2009 at 8:31 AM
The same problem - only one ValidationResult (email). Tested on EnterpriseLibrary 4.1.0.0.
Mar 12, 2009 at 11:10 AM
Edited Mar 12, 2009 at 11:33 AM
Link to the issue logged for this bug - http://entlib.codeplex.com/WorkItem/View.aspx?WorkItemId=10283


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Mar 12, 2009 at 12:30 PM
Thanks for reply. Validation from .config file other than App.config is really needed. Can't use App.config due the solution structure.