Validating Entity child collections

18 views
Skip to first unread message

martin

unread,
Feb 20, 2009, 9:56:20 AM2/20/09
to S#arp Architecture
Billy,

What do you think about extending the validation built into sharp to
validate lists of child entities.

I have implemented this in by base class:

public override bool IsValid()
{
return base.IsValid() && AreCollectionsValid();
}

protected virtual bool AreCollectionsValid()
{
return true;
}

protected static bool IsCollectionValid<T>(IEnumerable<T> list) where
T : Entity
{
var isValid = true;
foreach (var item in list)
{
isValid &= item.IsValid();
}

return isValid;
}

In any class that has an IList or other collection of Entity
subclasses I override AreCollections valid and make the appropriate
calls to IsCollectionValid passing in the relevant properties.

I was wondering whether this functionality could be baked in, at the
very least the IsCollectionValid method.

Martin

Billy

unread,
Feb 20, 2009, 10:45:34 AM2/20/09
to S#arp Architecture
We've been doing something similarly on my current project. We added
a [RequiresNestedValidation] attribute to the associations (either one-
to-many or many-to-one) which needs to be traversed during the
validation. We decided against auto-traversal in order to have a
little more control over how deep the validation would go. A
difficulty we had was coming up with a good consisent way to format
the report.

I'm just talking out loud now, but it seems like there are a few ways
we could report the validation problems of children items. For a many-
to-one association, it seems pretty straight-forward. The
IValidationResult would be the ClassContext and the PropertyName would
include the association class name. E.g., if you had a Customer
object with an association to a Company object which has a name, and
you left out the company name on the edit-customer-form, the
IValidationResult would hold ClassContext = typeof(Customer) and
PropertyName = "Company.Name".

Collection associations would be a bit trickier. Assume you had a
Contractor who had a number of Subcontractors assigned to it. Then,
on a form, you could enter the number of hours that each subcontractor
has put in for a given month. So, in a very simplistic manner (not
necessarily a recommendation for the actual model), the Contractor
would have a collection of SubcontractorHourEntry objects associated
with it - each having Subcontractor property and an Hours property.
(Let's ignore the month property for now.) So the form would have one
input box for each Subcontractor for you to enter the hours for that
month. Now assume that you have to enter at least 10 hours for each
subcontactor (don't ask why, that's just the requirement ;).
Accordingly, you'd have a [Min(Value=10)] above the
SubcontractorHourEntry.Hours property. So the question is, how would
you communicate back to the form which form inputs were invalid? On a
current project, we cheated - we used an Ext JS number input to
enforce entry on the client side. For this particular situation, if
you were doing it right, you'd probably include the subcontractor id
in each validation result PropertyName; e.g.,
SubcontractorHourEntry.Hours.For.Subcontractor.14. (Heh, it's a
fluent validation result. ;)

I don't think a scenario such as this could be automatically managed
by the underlying framework; you'd have to be able to inform the
validator what the known "key" is for the collection objects - in this
case each subcontractor's id. If you did want it automated, I suppose
the validator could like like the following:

public class Contractor {
[ValidCollection(Key="Subcontractor")]
IList<SubcontractorHourEntry> SubcontractorHourEntries { get;
protected set; }
}

I don't like the hard-coded "Subcontractor" string, but attributes are
pretty bitchy about taking lambdas or other dynamically calculated
direction. (They can't even be generic. :{ But even with the magic
string, it's an interesting idea - seems like something that could be
built into NHibernate Validator. Thoughts?

Billy

Martin Hornagold

unread,
Feb 20, 2009, 11:41:29 AM2/20/09
to sharp-arc...@googlegroups.com
Billy,

Since the objects in question must implement IValidatable ..
How about we make IValidatable and Validatable object generic and add a Key property.

Interface IValidatable<TKey>{
...
TKey Key {get;}
}

EntityWithTypeId can set this to its Id type and return the Id as the key.


Martin

Fabio Maulo

unread,
Feb 20, 2009, 12:30:30 PM2/20/09
to S#arp Architecture
For NHibernate.Validator users is enough using the [Valid] attribute
(for collections and relationships)

Martin Hornagold

unread,
Feb 20, 2009, 12:36:34 PM2/20/09
to sharp-arc...@googlegroups.com
Thanks Fabio. Didn't spot that attribute.
Much simpler ...
Although there is still the issue of how best to report back to the view.

-----Original Message-----
From: sharp-arc...@googlegroups.com [mailto:sharp-arc...@googlegroups.com] On Behalf Of Fabio Maulo
Sent: 20 February 2009 17:31
To: S#arp Architecture
Subject: Re: Validating Entity child collections


Fabio Maulo

unread,
Feb 20, 2009, 12:39:02 PM2/20/09
to S#arp Architecture
On 20 feb, 14:36, "Martin Hornagold"
<Martin.Hornag...@marstangroup.com> wrote:
> Thanks Fabio. Didn't spot that attribute.
> Much simpler ...
> Although there is still the issue of how best to report back to the view.
>

We are looking for contributors to develop the client-side validation.

Fabio Maulo

unread,
Feb 20, 2009, 12:47:57 PM2/20/09
to S#arp Architecture
On 20 feb, 14:39, Fabio Maulo <fabioma...@gmail.com> wrote:
> We are looking for contributors to develop the client-side validation.

Ah... seriously.
I add something in the trunk to know the definition of each constraint
for a given type.
You can use the ValidatorEngine to get a ValidationDefinition for a
given entity type
public IClassValidator GetValidator<T>()
The the classValidator has
IEnumerable<Attribute> GetMemberConstraints(string propertyName);
To know the configuration of a member.

Who are available can send me a private mail.

Martin Hornagold

unread,
Feb 20, 2009, 1:15:28 PM2/20/09
to sharp-arc...@googlegroups.com
Fabio,

Is there any way to determine which item in the collection validation results apply to when using this attribute?
It seems that we can only narrow it down to class context and property name.
This means that we don't know which parent property the error relates to (an issue if you have more than one property of the same type)
Or which item in the collection it relates to?

-----Original Message-----
From: sharp-arc...@googlegroups.com [mailto:sharp-arc...@googlegroups.com] On Behalf Of Fabio Maulo
Sent: 20 February 2009 17:31
To: S#arp Architecture
Subject: Re: Validating Entity child collections


Fabio Maulo

unread,
Feb 20, 2009, 1:30:55 PM2/20/09
to S#arp Architecture
It can be implemented... but we don't have an issue about this matter.
http://nhjira.koah.net/browse/NHV

I saw something strange in the life of NHV, really. NHV has more than
2000 downloads and I'm pretty sure that somebody else are using NHV
from S#arpA, but... the feedback, in practice, don't exists and NHV
has great potential especially for who are using it with NHibernate.

On 20 feb, 15:15, "Martin Hornagold"

Simone Busoli

unread,
Feb 20, 2009, 1:33:28 PM2/20/09
to sharp-arc...@googlegroups.com
Billy, I'm wondering why we are making IValidator on the ValidatableObject class thread static. I'm not sure I like all those TS around in the code. Since we have a service locator, why not just ask it for the validator?

Billy

unread,
Feb 20, 2009, 2:15:47 PM2/20/09
to S#arp Architecture
Your concern is valid Simone; I added an issue after Fabio brought
this up at http://groups.google.com/group/sharp-architecture/browse_thread/thread/bc6c6cab06be653c?hl=en
and will address, accordingly.

Billy


On Feb 20, 11:33 am, Simone Busoli <simone.bus...@gmail.com> wrote:
> Billy, I'm wondering why we are making IValidator on the ValidatableObject
> class thread static. I'm not sure I like all those TS around in the code.
> Since we have a service locator, why not just ask it for the validator?
>

Billy

unread,
Feb 20, 2009, 2:23:48 PM2/20/09
to S#arp Architecture
Voila: http://nhjira.koah.net/browse/NHV-38

Billy


On Feb 20, 11:30 am, Fabio Maulo <fabioma...@gmail.com> wrote:
> It can be implemented... but we don't have an issue about this matter.http://nhjira.koah.net/browse/NHV

Simone Busoli

unread,
Feb 20, 2009, 7:28:08 PM2/20/09
to sharp-arc...@googlegroups.com
Actually, I wanted to reply on that thread, sorry :)
I'm going to remove the validator field and just leave the property getter delegating to the service locator, is that fine for you? OTOH, I can't think of a reason why it was made thread static, maybe something left there when there was no service locator?

Luis Abreu

unread,
Feb 21, 2009, 9:31:53 AM2/21/09
to sharp-arc...@googlegroups.com
Why not let each subclass that needs that do the override you've done here?

Luis
> -----Original Message-----
> From: sharp-arc...@googlegroups.com [mailto:sharp-

Billy

unread,
Mar 7, 2009, 10:00:28 AM3/7/09
to S#arp Architecture
Daria has added some nice capabilities for the validation of child
collections: http://nhjira.koah.net/browse/NHV-38

Billy

On Feb 21, 7:31 am, "Luis Abreu" <lab...@gmail.com> wrote:
> Why not let each subclass that needs that do the override you've done here?
>
> Luis
>
> > -----Original Message-----
> > From: sharp-arc...@googlegroups.com [mailto:sharp-
> > archit...@googlegroups.com] On Behalf Of martin
> > Sent: sexta-feira, 20 de Fevereiro de 2009 14:56
> > To: S#arp Architecture
> > Subject: Validating Entity child collections
>
> > Billy,
>
> > What do you think about extending thevalidationbuilt into sharp to

Dario Quintana

unread,
Mar 7, 2009, 11:23:00 AM3/7/09
to sharp-arc...@googlegroups.com
I believe the release of NHV 1.2alpha is going to take place after the NH 2.1alpha release, or of course you can use the trunk.

Cheers


On Sat, Mar 7, 2009 at 1:00 PM, Billy <wmcca...@gmail.com> wrote:

Daria has added some nice capabilities for the validation of child
collections:  http://nhjira.koah.net/browse/NHV-38

Billy


--
Dario Quintana
http://darioquintana.com.ar

Billy

unread,
Mar 9, 2009, 1:48:43 AM3/9/09
to S#arp Architecture
I'll be including the trunk of NHibernate Validator in the next S#arp
Architecture release (which I hope to be coming in the next day).

Billy


On Mar 7, 10:23 am, Dario Quintana <conta...@darioquintana.com.ar>
wrote:
> I believe the release of NHV 1.2alpha is going to take place after the NH
> 2.1alpha release, or of course you can use the trunk.
>
> Cheers
>

Martin Hornagold

unread,
Mar 9, 2009, 4:47:59 AM3/9/09
to sharp-arc...@googlegroups.com
Fantastic.
Thank you both.

-----Original Message-----
From: sharp-arc...@googlegroups.com [mailto:sharp-arc...@googlegroups.com] On Behalf Of Billy
Sent: 09 March 2009 05:49
To: S#arp Architecture
Subject: Re: Validating Entity child collections


Martin

unread,
Mar 10, 2009, 5:34:52 AM3/10/09
to S#arp Architecture
Billy,

I wanted to clarify what you feel is the best way to get at this new
validating goodness.
Are you planning to change the ValidationResult or should I assume I
need to provide my own implementation in my project.

Martin

Billy

unread,
Mar 10, 2009, 8:32:23 AM3/10/09
to S#arp Architecture
Hi Martin,

Dario has addressed this in the latest version of NHibernate Validator
(http://nhjira.koah.net/browse/NHV-38), which is included on the trunk
of S#arp Architecture. Please let me know if this does not resolve
the issue; if it doesn't please provide details on what you are
expecting.

Thank you,
Billy

Martin Hornagold

unread,
Mar 10, 2009, 9:16:23 AM3/10/09
to sharp-arc...@googlegroups.com
Hi Billy,

I understand that the problem is fixed in NHibernate validator.
But if using S#arpArchitecture out of the box we are abstracted from InvalidValue through ValidationResult and so are restricted to the basic error message, class name and property name as before.
Am I missing something, or are we expected to implement our own Validator and ValidationResult to take advantage of the new functionality?

Martin

-----Original Message-----
From: sharp-arc...@googlegroups.com [mailto:sharp-arc...@googlegroups.com] On Behalf Of Billy
Sent: 10 March 2009 12:32
To: S#arp Architecture
Subject: Re: Validating Entity child collections


Billy

unread,
Mar 10, 2009, 9:19:10 AM3/10/09
to S#arp Architecture
Ah, I see what you're getting at. I will look into this further.
Please let me know if you have specific suggestions for how it should
be modified.

Thank you,
Billy


On Mar 10, 7:16 am, "Martin Hornagold"

Martin

unread,
Mar 11, 2009, 11:50:49 AM3/11/09
to S#arp Architecture
Billy,

I think I was confused by what the new interpolation was giving us.
The solution solves the wrong problem for me.
Looking at the tests in the NHibernate.Validator trunk the use case is
this:

public class SubcontractorHourEntry
{
public SubContractor Contrator { get; set; }

[Min(Value = 10,Message = "The min value in the SubContractor Id: $
{Contrator.Id} is invalid. Instead was found: ${Hour}")]
public int Hour { get; set; }
}

This solves your use case.

But personally I want to be write and HtmlHelper extension that loops
through the ValidationResult(s) and marks the invalid controls rather
than just providing an error summary.
I was previously unaware that InvalidValue already provides the
functionality I need through PropertyPath, Bean and RootBean.
PropertyPath is the simplest giving something like
"Contractor.SubContractorHourEntries[3].Hours"
If the textbox are named according to this path problem solved.

Anyway, have you got any objections to including the
NHibernate.Validator.InvalidValue within the ValidationResult class as
below.
That would solve my problem.

public class ValidationResult :
SharpArch.Core.CommonValidator.IValidationResult
{
public ValidationResult(InvalidValue invalidValue)
{
Check.Require(invalidValue != null, "invalidValue may not be
null");

InvalidValue = invalidValue;
}

public virtual Type ClassContext
{
get { return InvalidValue.BeanClass; }
}

public virtual string PropertyName
{
get { return InvalidValue.PropertyName; }
}

public virtual string Message
{
get{ return InvalidValue.Message;}
}

public virtual InvalidValue InvalidValue { get; protected set; }
}

Billy

unread,
Mar 11, 2009, 1:50:40 PM3/11/09
to S#arp Architecture
I could add the InvalidValue object to be included as a property of
SharpArch.Core.NHibernateValidator.CommonValidatorAdapter.ValidationResult,
but I couldn't add it to
SharpArch.Core.CommonValidator.IValidationResult. Consequently, you'd
need to cast it to get to the InvalidValue. But this would allow you
to write an application specific version of
SharpArch.Web.CommonValidator.MvcValidationAdapter, which would assume
the use of NHibernate Validator, for transferring the validation
errors to your view.

So in short, I'll expose the property on
SharpArch.Core.NHibernateValidator.CommonValidatorAdapter.ValidationResult
and leave IValidationResult untouched. (I'd be interested in seeing
any custom MvcValidationAdapter that you might end up writing to
accommodate the full potential of NHibernate Validator's
InvalidValue.)

Billy McCafferty

Martin Hornagold

unread,
Mar 11, 2009, 4:11:41 PM3/11/09
to sharp-arc...@googlegroups.com
Great. Thanks billy.
Will keep you posted on anything I do on the client side.


-----Original Message-----
From: Billy <wmcca...@gmail.com>
Sent: 11 March 2009 17:50
To: S#arp Architecture <sharp-arc...@googlegroups.com>
Subject: Re: Validating Entity child collections


Billy

unread,
Mar 11, 2009, 4:17:47 PM3/11/09
to S#arp Architecture
Grabbing the latest SharpArch.Core.NHibernateValidator.dll/pdb from
http://sharp-architecture.googlecode.com/svn/trunk/bin/ now has the
InvalidValue exposed, accordingly.

Billy


On Mar 11, 2:11 pm, "Martin Hornagold"
Message has been deleted

Martin Hornagold

unread,
Mar 12, 2009, 6:02:40 AM3/12/09
to sharp-arc...@googlegroups.com

Billy,

On reflection I am not that comfortable with strongly coupling to the
NHibernate.Validator.
I like the idea of being able to get at the InvalidValue if I need to,
but since the main property needed is PropertyPath.
I was wondering whether we could bake the property into S#arp by:

a) breaking and extending the IValidationResult interface to contain
Property path:

public interface IValidationResult
{
Type ClassContext { get; }
string PropertyName { get; }
string Message { get; }

string PropertyPath { get; }
}

b) providing an inherited interface

public IComplexValidationResult : IValidationResult
{
String PropertyPath { get; }
}

In the case of the ValidationResult implementation of S#arp this would
simply get the InvalidValue.PropertyPath:

public virtual string PropertyPath
{
get { return InvalidValue.PropertyPath; }
}

We could then either have alternative binders and validation adapters or
modify the existing ones to do the following (note there would need to
be a replace of indexing markers [] on PropertyPath to support
scripting, omitted for brevity):

foreach (IValidationResult/IComplexValidationResult validationResult
in validationResults) {
Check.Require(validationResult.ClassContext != null,
"validationResult.ClassContext may not be null");

string key = validationResult.PropertyPath ??
validationResult.ClassContext.Name +
(!string.IsNullOrEmpty(validationResult.PropertyName)
? "." + validationResult.PropertyName
: "");

modelStateDictionary.AddModelError(key,
validationResult.Message);
modelStateDictionary.SetModelValue(key, new
ValueProviderResult(null, null, null));
}

Thoughts?

Billy

unread,
Mar 15, 2009, 6:27:20 PM3/15/09
to S#arp Architecture
Hi Martin,

As an FYI, the RC 2 release allows you to get to the InvalidValue
property if you cast the IValidationResult to NHibernate Validator's
validation result. With respect to the abstracted solution you've
suggested, how would you concretely describe the difference between a
"PropertyName" and a "PropertyPath"? Do you see redundancy between
these two?

Billy


On Mar 12, 4:02 am, "Martin Hornagold"

Martin Hornagold

unread,
Mar 17, 2009, 7:35:21 PM3/17/09
to sharp-arc...@googlegroups.com
Billy,

There is a slight redundancy between PropertyName and PropertyPath.
However both are useful.
PropertyPath is a fully qualified PropertyName that describes where the invalid property is located in the object graph.
In many cases PropertyName will equal PropertyPath, so you could just have PropertyName return the path.
When the invalid property is in a child entity however they will be different.
Some people will want to just get at the name, others will want the full path to invalid property.
I assume this was the logic behind the two properties on InvalidValue.
I just felt that including this extra property in the CommonValidator could be useful to all users of IValidationResult.

Regards,

Martin

-----Original Message-----
From: sharp-arc...@googlegroups.com [mailto:sharp-arc...@googlegroups.com] On Behalf Of Billy
Sent: 15 March 2009 23:27
To: S#arp Architecture
Subject: Re: Validating Entity child collections


Reply all
Reply to author
Forward
0 new messages