Certainly there's no concept of doing validation on a read-only list or object. Since they are read-only they can't be changed, so there's nothing to validate.
In your scenario there must be some other, editable, object that you are using to add the new item. It is in that object that the validation must occur.
If you are allowing the user to atomically add a new item (like Format?) outside the context of a parent collection, then the only way to avoid collisions is during the save operation itself. The only way to know for sure that there's not a duplicate is by checking the other data in your database. While you could implement a helper validation rule that scans your read-only list for duplicates, that is just a best-guess and isn't the final word (at least in any multi-user setting).
Brian's solution requires that the parent hold the business rule. If you would prefer that the collection object hold the rule, then the collection would monitor Add and Remove to set the rule. The parent object would need to override IsValid to return MyBase.IsValid AndAlso _ChildCollection.IsValid. Using the later method allows you to have the parent object look all the way up it's tree with each branch being responsible for reporting it's validity level. In that regard, the collection would iterate it's children to see if they are valid and also impose the custom rule in the collection. The child can then handle valid for itself and any child objects. On and on all the way up the tree.
Jim Wooley
http://devauthority.com/blogs/jwooley/default.aspx
This is why IsValid is Overridable/virtual in BusinessListBase - so you can override it to implement collection-wide rules if needed (must make sure to call the base implementation too!!). Jim's suggestion of checking the rules in Add/Remove is wise - but should also include Set and in a ListChanged event handler.
ajj, I haven't added validation to editable collections because I'm not really sure what form that would take. In other words, what would you expect such validation logic to look like within your collection class? I think the concept is a great one, I just haven't thought of a clear solution in terms of design/usage.
I faced that problem in CSLA1.0. I did finally eek out a solution which has been working, but I sooooo wished there was some validation mechanism in Editable Collections. Here is the scenario that I faced.
All Persons and Organizations can have 0...many addresses. All addresses are in a single DB table. If the entity has more than one address, one of the addresses must be marked as a Default so that in situations where the UI etc only wants a single address for a given entity, the DB will know which one to serve up.
Problem is further complicated because a given Person (or organization) can wear many hats, and the "Default" address of given entity may depend on the hat placed on the entity by the UI (or DB) etc. at that given moment.
When I bring up a Person, along with the collection of addresses, I need to evaluate if One and Only One address is marked as Default - and if not a rule must be broken. The way I handled it was to insert another object (Entity) in the hierarchy between a Person (or organization) and its Addresses (or Phones, or Emails), and create a rule for that Entity Object.
Hence Entity.IsValid meant, among other things, that each of its collections that have > 1 item, had one of the items marked as Default.
Thus, there are situations in which, each member of a collection may be Valid, but the collection itself may not be valid at a given moment. It may help to have a simpler mechanism to evaluate that.
Jav
Has anyone come up with a good solution or this?
my scenerio is simple. I have an editable collection of Product objects. Each product has a ProductName property. No two products can have the same ProductName.
I am displaying the objects in a grid that supports the System.ComponentModel.IDataErrorInfo interface and I would REALLY like it if the invalid condition could somehow mark the individual objects as invalid since that would make the grid display each row as invalid when the same name was entered 2 times.
Waiting for someone smarter than me...
David
Raise an
event to the collection when the ProductName property changes on a product object. Pass a reference of the product object when
the event is raised. The Collection
should loop through the product objects to check if there are duplicate product
names. If there are, call a method on
the product object to set the “duplicate product name” rule to true. If there isn’t a duplicate product name, call
a method on the product object to set the “duplicate product name” rule to
false. I did this on CSLA 1.0 and it
worked.
You want both rows to go into error, or just the new one?
The new one is easy: put a rule on your Name property that
simply loops through the Parent collection (a child has reference to its
parent) looking for a match of the value. If you find one, return false. The Admin.Roles
class in ProjectTracker does this.
If you want both to go into error it is a little harder, because
you’ll need to put a Friend/internal method on your child class so the
new object, when it finds a match (using the same algorithm I just described)
can tell the matching object to invoke its own rule check for the Name
property. To avoid duplicate work and/or a recursive issue, you’ll need
to do some extra work: an extra rule method that just goes false at priority 0,
and the Parent-scan rule at priority 1.
Rocky
From: DCottle
[mailto:cslanet@lhotka.net]
Sent: Friday, June 22, 2007 12:50 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Validation of collection
Has anyone come up with a good solution or this?
my scenerio is simple. I have an editable collection of Product
objects. Each product has a ProductName property. No two products
can have the same ProductName.
I am displaying the objects in a grid that supports the
System.ComponentModel.IDataErrorInfo interface and I would REALLY like it if
the invalid condition could somehow mark the individual objects as invalid
since that would make the grid display each row as invalid when the same name
was entered 2 times.
Waiting for someone smarter than me...
David
Brilliant! The new row in error was sufficient, and very simple thanks to malloc1024 suggestion above.
I may have bastardized my objects, because I do not seem to be able to get to the Parent collection from my object. What is this reference supposed to be called so I can track down what I screwed up?
Thanks again Rocky and malloc...
David
If your collection is a BusinessListBase then Parent should be a
protected property of your child object.
If the parent is an EditableRootListBase then the Parent
property is null/Nothing because the object isn’t a “child”.
It could be that the Parent property is marked as hidden to
Intellisense, but it is there.
Rocky
From: DCottle
[mailto:cslanet@lhotka.net]
Sent: Friday, June 22, 2007 3:13 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Validation of collection
Brilliant! The new row in error was sufficient, and very simple thanks
to malloc1024 suggestion above.
I may have bastardized my objects, because I do not seem to be able to get
to the Parent collection from my object. What is this reference supposed
to be called so I can track down what I screwed up?
Thanks again Rocky and malloc...
David
I'm facing this same issue. I have a collection which is having a Percentage field. The total of this percentage field should be 100. But suppose if I have 2 records with percentage of 60 & 40 then a error is thrown as soon as the record is loaded from database or a new record is added.
How I can disable that error, can somebody pls help.
Copyright (c) Marimer LLC