I ran into a problem recently that had me scratching my head. I have a DTO with Enterprise Library Validation like so:
public class Person
{
[RangeValidator(0,RangeBoundaryType.Inclusive,10,RangeBoundaryType.Inclusive,MessageTemplate="{0} is an invalid Person Id")]
public int PersonId { get; set; }
[StringLengthValidator(10, MessageTemplate = "Name is 10 characters")]
[NotNullValidator(MessageTemplate="{1} Can’t be null}")]
public string PersonName { get; set; }
public DateTime DateOfBirth { get; set; }
public DateTime? DateOfDeath { get; set; }
This person class was served up by a Factory (Builder, really) like so. I threw some test data into the class just so I can inspect value in the round trip
[DataObject(true)]
public class PersonFactory
{
static Collection<Person> family;
static PersonFactory()
{
family = new Collection<Person>();
family.Add(new Person(0, "Jackie", DateTime.Parse("05/04/1951"), null));
family.Add(new Person(1, "Tito", DateTime.Parse("10/15/1953"), null));
family.Add(new Person(2, "Jermaine", DateTime.Parse("12/11/1954"), null));
family.Add(new Person(3, "Marlon", DateTime.Parse("03/12/1957"), null));
family.Add(new Person(4, "Michael", DateTime.Parse("08/29/1958"), DateTime.Parse("06/25/2009")));
}
public static Collection<Person> GetFamily()
{
return family;
}
public static void UpdatePerson(Person person)
{
. . .
}
public static void InsertPerson(Person person)
{
. . .
}
I then created a simple Web Form to handle the updating using an Object Data Source and a Grid View:
<asp:GridView ID="GridViewFamily" runat="server" AutoGenerateColumns="False"
DataSourceID="ObjectDataSourceFamily">
<Columns>
<EditItemTemplate>
<asp:TextBox ID="TextBoxPersonId" runat="server" Text=’<%# Bind("PersonId") %>‘></asp:TextBox>
<cc1:PropertyProxyValidator ID="PropertyProxyValidatorUpdatePersonId" runat="server"
ControlToValidate="TextBoxPersonId" PropertyName="PersonId"
SourceTypeName="TestWebProject.Person" Display="None"></cc1:PropertyProxyValidator>
<cc2:ValidatorCalloutExtender ID="PropertyProxyValidator_UpdatePersonId_ValidatorCalloutExtender"
runat="server" Enabled="True" TargetControlID="PropertyProxyValidatorUpdatePersonId">
</cc2:ValidatorCalloutExtender>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text=’<%# Bind("PersonId") %>‘></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="PersonName" SortExpression="PersonName">
. . .
</Columns>
</asp:GridView>
So far, so good

I then added a Details View for inserting and associated it with the same Object Data Source:
<asp:DetailsView ID="DetailsViewInsertFamily" runat="server" AutoGenerateRows="False"
DataSourceID="ObjectDataSourceFamily" DefaultMode="Insert" Height="50px"
Width="125px">
<Fields>
<InsertItemTemplate>
<asp:TextBox ID="TextBoxInsertPersonId" runat="server"
Text=’<%# Bind("PersonId") %>‘></asp:TextBox>
<cc1:PropertyProxyValidator ID="PropertyProxyValidatorInsertPersonId" runat="server"
ControlToValidate="TextBoxInsertPersonId" PropertyName="PersonId"
SourceTypeName="TestWebProject.Person" Display="None"></cc1:PropertyProxyValidator>
<cc2:ValidatorCalloutExtender ID="PropertyProxyValidator_InsertPersonId_ValidatorCalloutExtender"
runat="server" Enabled="True"
TargetControlID="PropertyProxyValidatorInsertPersonId">
</cc2:ValidatorCalloutExtender>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text=’<%# Bind("PersonId") %>‘></asp:Label>
</ItemTemplate>
</asp:TemplateField>
. . .
</Fields>
</asp:DetailsView>
Things go awry. When I try and run an update on the screen, I get the following error:
Index was outside the bounds of the array.
After a little thought, I realized that the Insert Template is firing off the validation on the update postback. I handled the error by adding a ValueConvert event handler to the PropertyProxyValidator on the insert:
protected void PropertyProxyValidatorInsertPersonId_ValueConvert(object sender, Microsoft.Practices.EnterpriseLibrary.Validation.Integration.ValueConvertEventArgs e)
{
int result = 0;
bool ok = Int32.TryParse(e.ValueToConvert.ToString(), out result);
if (!ok)
{
e.ConvertedValue = -1;
}
}
However, handling the error then gives me this:

Notice how the Validator is firing for Details View – even though the Updating is from the Grid View.
I then put the details view into an Update Panel to see if that will isolate the GridView’s Update – no luck. I then thought of two programic solutions:
· On the Updating Event, disable the Insert Validators
· Adding a RuleSet for updating and inserting
Both solutions seem less than ideal to me – Adding a ruleset uses duplicates code and makes the code base harder to maintain – as well as coupling the DTO to the User Layer – which is never good. Using some event to enable/disable the validators seems to be better from a coding perspective so I will implement that