EntLib6 - EntLibConfig - Custom Validator not in menu

Topics: Building and extending application blocks, Enterprise Library Core, Validation Application Block
Apr 3, 2014 at 12:17 AM
Edited Apr 3, 2014 at 12:18 AM
Hi,

I am attempting to add a custom validator to the list of validators within EntLib 6's EntLibConfig.

I created the ValidatorData and Validator classes and dropped the DLL into the same folder as EntLibConfig.exe, but the validator does not appear in the menu of available validators.

I based the code upon the AndCompositeValidator and the TypeConvertValidator. Not sure where the issue would be. Any help is appreciated.

Thanks,

Chris
// CastCompositeValidatorData.cs
using System;
using System.Collections.Generic;
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Design;
using System.ComponentModel;
using Microsoft.Practices.EnterpriseLibrary.Validation.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Validation;

namespace MyProject.Validators
{
    [ResourceDisplayName(ResourceType = typeof(Custom), ResourceName = "CastCompositeValidatorDisplayName")]
    [ResourceDescription(ResourceType = typeof(Custom), ResourceName = "CastCompositeValidatorDisplayDescription")]
    public class CastCompositeValidatorData : ValidatorData
    {
        private static readonly AssemblyQualifiedTypeNameConverter typeConverter = new AssemblyQualifiedTypeNameConverter();

        public CastCompositeValidatorData() { Type = typeof(CastCompositeValidator); }

        public CastCompositeValidatorData(string name)
            : base(name, typeof(CastCompositeValidator))
        { }

        private const string ValidatorsPropertyName = "";
        [ConfigurationProperty(ValidatorsPropertyName, IsDefaultCollection = true)]
        [PromoteCommands]
        public ValidatorDataCollection Validators
        {
            get { return (ValidatorDataCollection)this[ValidatorsPropertyName]; }
        }

        [Browsable(false)]
        public override string MessageTemplate
        {
            get { return base.MessageTemplate; }
            set { base.MessageTemplate = value; }
        }

        [Browsable(false)]
        public override string MessageTemplateResourceName
        {
            get { return base.MessageTemplateResourceName; }
            set { base.MessageTemplateResourceName = value; }
        }
        
        [Browsable(false)]
        public override string MessageTemplateResourceTypeName
        {
            get { return base.MessageTemplateResourceTypeName; }
            set { base.MessageTemplateResourceTypeName = value; }
        }
        
        [Browsable(false)]
        public override string Tag
        {
            get { return base.Tag; }
            set { base.Tag = value; }
        }

        private const string TargetTypePropertyName = "targetType";
        [ConfigurationProperty(TargetTypePropertyName, IsRequired = true)]
        [Editor(CommonDesignTime.EditorTypes.TypeSelector, CommonDesignTime.EditorTypes.UITypeEditor)]
        [BaseType(typeof(object))]
        public string TargetTypeName
        {
            get { return (string)this[TargetTypePropertyName]; }
            set { this[TargetTypePropertyName] = value; }
        }

        public Type TargetType
        {
            get { return (Type)typeConverter.ConvertFrom(TargetTypeName); }
            set { TargetTypeName = typeConverter.ConvertToString(value); }
        }

        protected override Validator DoCreateValidator(
            Type targetType,
            Type ownerType,
            MemberValueAccessBuilder memberValueAccessBuilder,
            ValidatorFactory validatorFactory)
        {
            List<Validator> childValidators = new List<Validator>(this.Validators.Count);
            foreach (IValidatorDescriptor validatorData in this.Validators)
            {
                childValidators.Add(validatorData.CreateValidator(targetType, ownerType, memberValueAccessBuilder, validatorFactory));
            }

            return new CastCompositeValidator(TargetType, childValidators.ToArray());
        }
    }
}
// CastCompositeValidator.cs
using System.Collections.Generic;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Validation.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using System;
using System.ComponentModel;
using System.Globalization;

namespace MyProject.Validators
{
    [ConfigurationElementType(typeof(CastCompositeValidatorData))]
    public class CastCompositeValidator : Validator
    {
        private IEnumerable<Validator> validators;
        private Type targetType;

        public CastCompositeValidator(Type targetType, params Validator[] validators)
            : base(null, null)
        {
            this.targetType = targetType;
            this.validators = validators;
        }

        public override void DoValidate(object objectToValidate,
            object currentTarget,
            string key,
            ValidationResults validationResults)
        {
            TypeConverter typeConverter = TypeDescriptor.GetConverter(targetType);
            object convertedValue = typeConverter.ConvertFromString(null, CultureInfo.CurrentCulture, objectToValidate.ToString());
            foreach (Validator validator in this.validators)
            {
                validator.DoValidate(convertedValue, currentTarget, key, validationResults);
            }
        }

        protected override string DefaultMessageTemplate
        {
            get { return null; }
        }

        public IEnumerable<Validator> Validators
        {
            get
            {
                return this.validators;
            }
        }
    }
}
Apr 3, 2014 at 5:13 AM
It seems to work OK for me with the posted code.

How are you starting the configuration tool? Are you using the integrated tool within Visual Studio? If so, then you will need to add the path to the custom validator binary to the Solution Property "Enterprise Library v6 binaries paths" . That value might look like: packages\EnterpriseLibrary.Common.6.0.1304.0\lib\NET45;packages\EnterpriseLibrary.Validation.6.0.1304.0\lib\NET45;c:\MyValidators\

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Apr 3, 2014 at 3:33 PM
Randy,

Thank you for the quick response.

I downloaded the EntLib 6 binaries and placed them in a folder on my C drive. I then copied the custom DLL to the folder. Then I ran EntLibConfig.exe. Is that what you are doing as well? I just downloaded the binaries once more and tried the same with no success.

I also had to put the following DLLs in the folder to get the configuration console to run because it would otherwise fail on startup.

Microsoft.Practices.EnterpriseLibrary.Common.dll
Microsoft.Practices.EnterpriseLibrary.Validation.dll
Microsoft.Practices.EnterpriseLibrary.SqlConfigurationSource.dll
Microsoft.Practices.Unity.dll

Thanks again,

Christian