System.InvalidOperationExceptionSystem.InvalidOperationException
Old forum URL: forums.lhotka.net/forums/t/3321.aspx
bassplayer posted on Friday, August 03, 2007
I'm currently using the 2.0 of CSLA (VB.NET) and when I have the following Validation Rule:
Protected Overrides Sub AddBusinessRules()
ValidationRules.AddRule( _
AddressOf Validation.CommonRules.StringRequired, "DisplaySort")
ValidationRules.AddRule( _
AddressOf Validation.CommonRules.StringMaxLength, _
New CommonRules.MaxLengthRuleArgs("DisplaySort", 4))
ValidationRules.AddRule(AddressOf NoDuplicates, "DisplaySort")
End Sub
Private Function NoDuplicates(ByVal target As System.Object, _
ByVal e As RuleArgs) As Boolean
Dim parent As Units = CType(Me.Parent, Units)
For Each item As Unit In parent
If item.DisplaySort = _displaySort AndAlso Not ReferenceEquals(item, Me) Then
e.Description = "Display Sequence must be unique"
Return False
End If
Next
Return True
End Function
This is similar to the Role.vp example in the ProjectTracker20vb project:
Protected Overrides Sub AddBusinessRules()
ValidationRules.AddRule( _
AddressOf Csla.Validation.CommonRules.StringRequired, "Name")
ValidationRules.AddRule(AddressOf NoDuplicates, "Id")
End Sub
Private Function NoDuplicates(ByVal target As Object, _
ByVal e As Csla.Validation.RuleArgs) As Boolean
Dim parent As Roles = CType(Me.Parent, Roles)
For Each item As Role In parent
If item.Id = mId AndAlso Not ReferenceEquals(item, Me) Then
e.Description = "Role Id must be unique"
Return False
End If
Next
Return True
End Function
Now, in order to have this called, I had to add the following to the New() method:
Private Sub New()
MarkAsChild()
ValidationRules.CheckRules()
End Sub
I notice the method ValidationRules.CheckRules() was NOT called in the Role.vb file, thus was never called.
The exception I'm getting is:
System.InvalidOperationException was unhandled
Message="An error occurred creating the form. See Exception.InnerException for details.
The error is: DataPortal.Fetch failed (System.InvalidOperationException:
Invalid rule method (instance methods of the target object not allowed):
NoDuplicates\r\n at Csla.Validation.ValidationRules.ValidateHandler(MethodInfo method) in
D:\\cad911\\CSLA20VB\\Csla\\Validation\\ValidationRules.vb:line 593\r\n
at Csla.Validation.ValidationRules.ValidateHandler(RuleHandler handler) in
D:\\cad911\\CSLA20VB\\Csla\\Validation\\ValidationRules.vb:line 580\r\n
at Csla.Validation.ValidationRules.AddRule(RuleHandler handler, String propertyName) in
D:\\cad911\\CSLA20VB\\Csla\\Validation\\ValidationRules.vb:line 389\r\n
What I need to do is check the make sure there are no duplicate entries for my business object. I need the ErrorProvider to turn on when there is a duplicate on my WinForm. What am I doing wrong?
When the user is presented with a blank form that is databound to this business object, I want this check to happen when the user types in a value in the field and then tabs to the next field.
RockfordLhotka replied on Saturday, August 04, 2007
You shouldn't call ValidationRules methods in the constructor of your class - that's too early.
If you want a new object to start out validated, make the call in DataPortal_Create():
<RunLocal()> _
Private Overloads Sub DataPortal_Create()
ValidationRules.CheckRules()
End Sub
bassplayer replied on Monday, August 06, 2007
Okay. I changed it to do this:
#Region " Factory Methods "
Public Shared Function NewUnit() As Unit
'Return New Unit
Return DataPortal.Create(Of Unit)()
End Function
Friend Shared Function GetUnit(ByVal dr As Csla.Data.SafeDataReader) As Unit
Return New Unit(dr)
End Function
Private Sub New()
'MarkAsChild()
End Sub
Private Sub New(ByVal dr As Csla.Data.SafeDataReader)
MarkAsChild()
Fetch(dr)
End Sub
#End Region
#Region " Data Access "
<RunLocal()> _
Protected Overrides Sub DataPortal_Create()
MarkAsChild()
ValidationRules.CheckRules()
End Sub
And I still get the System.InvalidOperationException. I modeled this way after the Project.vb example in ProjectTracker20vb:
#Region " Factory Methods "
Public Shared Function NewProject() As Project
If Not CanAddObject() Then
Throw New System.Security.SecurityException( _
"User not authorized to add a project")
End If
Return DataPortal.Create(Of Project)()
End Function
<RunLocal()> _
Protected Overrides Sub DataPortal_Create()
mId = Guid.NewGuid
Started = CStr(Today)
ValidationRules.CheckRules()
End Sub
What I don't understand is that either it the ValidationRules.CheckRules() being called in the constructor or being called in the DataPortal_Create(), its still being called when the object is created.
RockfordLhotka replied on Monday, August 06, 2007
It is true that the constructor and DP_C() are invoked when the
object is created, but they occur at different times in the process.
Obviously the constructor is first, by definition.
Then a bunch of initialization occurs.
Then DP_C() is invoked.
Calling ValidationRules.CheckRules() before that initialization
is the problem.
Rocky
Copyright (c) Marimer LLC