Apply HasSelfValidation attribute on Metadata target class

Topics: Validation Application Block
Apr 23, 2010 at 6:49 AM
Edited Apr 23, 2010 at 6:53 AM

 

Hi~

I'm currently trying EntLib 5.0 with Validation Application Block in my pioneer project. I like the idea that VAB allows the seperation of "implementation class" and "validation class" by applying Metadata attribute on the "implementation class" which targets "validation class" which contains the validation logic.

While I am happy with this feature, I found that I can't put my SelfValidation logic in the "validation class", the validation results, either Validation.Validate( myObj ) or ValidationFactory.CreateValidator( typeof(ImplClass), just doesn't work ( nothing's wrong and SelfValidator does not appear, sample code at later part of this post). Is there a design concern about this constraint, or I did something wrong?

Thx~

 

Here's the sample code

 

/// This Is The Implmentation Class

    [MetadataType(typeof(InvoiceValidation))]
    public partial class Invoice
    {
        public Invoice()
            : base()
        {
           ....
        }


        public string Name{ get; set; }

        public int Price{ get; set; }
    }


/// This Is The Validation Class

    [HasSelfValidation]
    public class InvoiceValidation
    {
        [StringLengthValidator(
           1, 10,
           MessageTemplate = "Name must be between 1 and 10 characters",
           Tag = "Name")]
        string Name { get; set; }

        [RangeValidator(
             0, RangeBoundaryType.Inclusive, 0, RangeBoundaryType.Ignore,
             MessageTemplate = "Price must be larger than 0",
             Tag = "Price")]
        int Price { get; set; }

        [SelfValidation]
        public void CustomValidate(ValidationResults pResults)
        {
            pResults.AddResult(new ValidationResult("ErrorMessage1", typeof(Invoice), "", "", null));
        }


    }

        public ValidationResults Validate()
        {

            /// results1 here contians nothing

            ObjectValidator validator1 = new ObjectValidator(typeof(Invoice));
            ValidationResults results1 = validator1.Validate(invoiceInstance);

            /// validator2 here contains nothing

            Validator validator2 = ValidationFactory.CreateValidator(typeof(Invoice), string.Empty);
            ValidationResults results2 = validator2.Validate(invoiceInstance);

            ///

            return results;
        }

Apr 23, 2010 at 7:36 AM

I'm not sure if this is a bug or by design, we'll confirm this. 

 

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

May 11, 2010 at 3:26 AM

Thanks for your reply, I'm wondering if there's any feedback from the design team?

May 11, 2010 at 3:27 AM

Not yet, Chris Tavares directly answers on this forum.

 

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

Sep 10, 2010 at 4:09 PM

I'm also searching for a solution that would allow the use of self validation while also using a metadatatype.

Sep 12, 2010 at 7:02 PM
Edited Sep 18, 2010 at 8:48 PM

It is not supported out of the box right now, but look at this blog post to see how to do this.

I hope this helps.

Sep 13, 2010 at 5:20 AM

It's not supported by design right now. The assumption is that if you're doing self-validation, you're probably doing something against your private members, which are, of course, not available to the metadata class (or any other class). If it was validation against just the public interface of the class, you could just write it as a custom validator.

We could see about relaxing the restriction in the future if the scenario is compelling enough.

 

Sep 13, 2010 at 4:40 PM

The problem for me was that if I chose to use the metadatatype at all, I no longer had the option of self-validation (even in the class the metadatatype described).  For me there were properties that were dependent on very specific values of other properties. I felt that this edge case seemed better suited for self-validation and not a custom validator due to the lack of reuse (I tend to build custom validators if I can see at least one case of reuse).

Sep 13, 2010 at 4:45 PM

My ultimate goal would be to keep the validations, specific to the types I'm validating, as close "together" as possible and Dot_net_junkie provides a solution that does just that.

Thanks!

p.s. dot_net_junkie, EnterpriseLibraryContrib might make a good home for your solution...

Sep 13, 2010 at 10:11 PM

Hi themortalcoil,

I agree with you that EntlibContrib would be a very good place for my stuff, since I'm building more of these solutions for VAB (such as this, this, and this). I even asked this once at the contrib project, but never got any response.

Cheers.