How can I get the object validator to pass key names to sub validators

Topics: Validation Application Block
Apr 29, 2010 at 9:41 PM
Edited Apr 29, 2010 at 9:58 PM

Let's say I have a class UserInformation, with a property PrimaryPhone of type PhoneInfo. PhoneInfo has two properties, PhonePrefix and PhoneBody.

I want to set up validation on types UserInformation and PhoneInfo. UserInformation has an ObjectValidator on PrimaryPhone that refers to the PhoneInfo validated type.

In MVC templates, as it is done correctly, child properties are bound through validation using a . separator. So, for example, the PhonePrefix field under UserInformation's PrimaryPhone would appear as the argument in a ValidationMessage as: = Html.ValidationMessage("PrimaryPhone.PhonePrefix",......

It is impossible then to align the Enterprise Library Validation keys with the MVC validation keys for grand-child properties.

Unfortunately, I can't figure out a way to get the Enterprise Library Validation Framework to append child validation keys the same way, to appear as PrimaryPhone.PhonePrefix. There is no control over this.

There should be the option, in ObjectValidator, to specify they key that gets appended to the beginning of validation keys in its child validators.

Another issue would be if, lets say you have PrimaryPhone and SecondaryPhone as properties to validate. How would you differentiate between the keys produced as a result of validation, if you wanted to use the same validated type?

Apr 30, 2010 at 1:50 AM

One suggestion would be to use the Tag property to distinguish the properties althought it doesn't mean it would change the error message and it wouldn't support a deep hierarchy.  The other option, (and I think the better one) would be to create your own custom object validator.  It would be so hard as you can just base your code from the ObjectValidator source.  You'll just add the extra logic of constructing the error messages the way you want it to.

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Apr 30, 2010 at 3:05 PM
Edited Apr 30, 2010 at 3:06 PM
First I want to say thanks for you very quick responses to all of my questions. Once I create a custom validator, how do I get its assembly to appear in the list of Available Assemblies, when selecting a custom validator, in the dialog box "Browsing for types that derive from Validator with a Configuration Element Type of CustomValidatorData"?
Apr 30, 2010 at 3:36 PM
Edited Apr 30, 2010 at 3:41 PM

Ok, so I have two issues now.

How to properly override the ObjectValidator

I need to override the DoValidate method of ObjectValidator to somehow pass the validation keys through to the deep hierarchy. I looked at the source code and noticed that, in line 155, it calls:

// reset the current target and the key this.GetValidator(objectToValidateType).DoValidate(objectToValidate, objectToValidate, null, validationResults);

Let's say I change this to pass a key "PrimaryPhone." to the key argument. Would this get passed down to the child validators of that object validator?

How to get child validation results of Composite Validator to actually appear in Nested Validation Results

I can never seem to find a way to get NestedValidationResults populated when running validations. Even when I run an And Composite validator, the validation results all get flattened and put into the Enumerated validation results of the base validator. How can I get the And Composite Validator to properly put its validation results in the NestedValidationResults? This would solve all of the above issues, in that I could recursively dig into the validation results tree and append prefixes for each level of nesting

How do I get my custom validator to not cause the enterprise library gui to crash?

I created a custom validator called NestedObjectValidator that inherits from ObjectValidator, with ConfigurationElement NestedObjectValidatorData. See the below code:

[ConfigurationElementType(typeof(ObjectValidatorData))] public class NestedObjectValidator : ObjectValidator { // constructor logic here // overrides here /// <summary> /// Gets or sets which key prefix will be appended to validation keys of child validation results /// </summary> public string KeyPrefixToAppend { get; set; } }

public class NestedObjectValidatorData : CustomValidatorData { private const string TargetRulesetPropertyName = "targetRuleset"; /// <summary> /// Gets or sets the name for the target ruleset for the represented validator. /// </summary> [ConfigurationProperty(TargetRulesetPropertyName)] public string TargetRuleset { get { return (string)this[TargetRulesetPropertyName]; } set { this[TargetRulesetPropertyName] = value; } } private const string ValidateActualTypePropertyName = "validateActualType"; /// <summary> /// Gets or sets the value indicating whether to validate based on the static type or the actual type. /// </summary> [ConfigurationProperty(ValidateActualTypePropertyName, DefaultValue = false)] public bool ValidateActualType { get { return (bool)this[ValidateActualTypePropertyName]; } set { this[ValidateActualTypePropertyName] = value; } } private const string KeyPrefixToAppendPropertyName = "keyPrefixToAppend"; /// <summary> /// Gets or sets which key prefix will be appended to validation keys of child validation results /// </summary> [ConfigurationProperty(ValidateActualTypePropertyName, DefaultValue = false)] public string KeyPrefixToAppend { get { return (string)this[KeyPrefixToAppendPropertyName]; } set { this[KeyPrefixToAppendPropertyName] = value; } } }

Since I could not figure out how to get my library to appear in the list of assemblies available for custom validators, I manually added this validator to the configuration file. Whenever I try to open the enterprise library configuration editor, I get the ambiguous error message "Error Loading Section Validation" What am I doing wrong? I can't seem to ever build custom validators and seem to get them working correctly in the configuration tool.

Apr 30, 2010 at 3:37 PM
Unfortunately, this discussion board doesnt work well with copying and pasting code. Any good alternatives for this?
May 4, 2010 at 10:29 AM

Hi,  

For the following questions "How to properly override the ObjectValidator" and "How do I get my custom validator to not cause the enterprise library gui to crash?", your CustomValidator should implement the Validator abstract class. Please see this blog http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=47 for the sample of a CustomValidator.  

As for, "Let's say I change this to pass a key "PrimaryPhone." to the key argument. Would this get passed down to the child validators of that object validator?" . For what I know it will not be passed to the child validator. By the way, do your child class properties would also use your custom validator?  If it is, then as what advise initially by my colleague on this thread you can just add the extra logic of constructing the error messages the way you want it to.  

As for the "How to get child validation results of Composite Validator to actually appear in Nested Validation Results" I already answered this in the separate thread http://entlib.codeplex.com/Thread/View.aspx?ThreadId=211410. I don't know how bad would be my ideas on how you can achieve this but if you really want to do this, how about trying to put all your validators in an OrCompositeValidator or you may also opt to create your own copy of ValidationResult and ValidationResults class where in there you can already set the NestedValidationResults property Set Accessor to public.  

Gino Terrado
Global Technology and Solutions
Avanade, Inc.
 entlib.support@avanade.com

 

May 4, 2010 at 10:31 AM

Btw, you can use the "Insert Code Snippet (</>)" button here when pasting a code. Hth :-)

May 4, 2010 at 3:31 PM
So, as of today all of these issues have been resolved! "How do I get my custom validator to not cause the enterprise library gui to crash?" I reazlied that when I was manually configurating to add that validator, I didn't put just the assembly name without the class name, and didnt include the version of PublicKeyToken=null information about the assembly. Once I added those, it was fixed. I actually posted the same question on another thread :) And after much prodding I successfully implemented a custom validator that does what I need at http://entlib.codeplex.com/Thread/View.aspx?ThreadId=211410