I am trying to use BrokenRulesCollection as a property of a Command Object, but I am unable to create a new instance of a BrokenRule and Add it to the collection.
In summary, inside the Command Object, I am calling other CSLA Objects to carry out some Database Updates for several Objects inside a Loop.
I want to capture all possible errors including Validation Errors, and return them in a collection object which can be accessed via the UI code.
I am thinking to use the BrokenRulesCollection, is this a good idea?
Or should I use List of String (Arrays) to capture the errors ...etc and return the resutls as a simple array ?
Why I cannot create BrokenRules objects ?
Tarek.
In general terms - I would not use BrokenRule / BrokenRuleCollection for this purpose. These classes exist for a specific responsibility on BusinessRules.
1. Your other CSLA objects may have structure/tree of BrokenRules (not just on the root object).
2. All possible errors (Exceptions) may not map directly to a BrokenRules, f.ex Inner exceptions may hold essential data. Or how about DataPortalException that may or may not have a BusinessException (as inner exception).
I believe you should create your own structure for this purpose and send back to your client application.
Hi Jonny,
Yes, I agree with you. This is what I have done to report errors back to the UI:
Public Shared Function RefreshDBFields(ByVal theUserCtrlInfoPack As UserCtrlInfoPack, ByVal DoGetCountOnly As Boolean) As RefreshDBFieldsCommand
Dim result As RefreshDBFieldsCommand
If Not AppSecurity.GetSingleton.IsUserAuthorized(AppSecurity.CodesApp.eHRMD, AppSecurity.CodesActions.RefreshDBFlds, AppSecurity.CodesDataTypes.SPMSForm, theUserCtrlInfoPack) Then
Throw New System.Security.SecurityException( _
String.Format( _
My.Resources.NotAuthErrorPrm2, _
theUserCtrlInfoPack.AuthUserID, _
AppSecurity.CodesActions.RefreshDBFlds.ToString, _
SPMSForm.GetSPMSFormInits.GetObjectName, "<all>"))
End If
result = DataPortal.Execute(Of RefreshDBFieldsCommand)(New RefreshDBFieldsCommand(theUserCtrlInfoPack, DoGetCountOnly))
Return result
End FunctionPublic Class RefreshDBFieldsCommand
Inherits CommandBasePrivate mRecordsToBeRefreshedCnt As Integer
Private mRecordsRefreshedCnt As Integer
Private mDoGetCountOnly As Boolean
Private mRecordVersion As Integer
Private mUserCtrlInfoPack As UserCtrlInfoPack
Private mMessages As New List(Of String)
Private mSuccess As BooleanPublic ReadOnly Property RecordsToBeRefreshedCnt() As Integer
Get
Return mRecordsToBeRefreshedCnt
End Get
End PropertyPublic ReadOnly Property RecordsRefreshedCnt() As Integer
Get
Return mRecordsRefreshedCnt
End Get
End PropertyPublic ReadOnly Property Messages() As String()
Get
Return mMessages.ToArray()
End Get
End PropertyPublic ReadOnly Property Success() As Boolean
Get
Return mSuccess
End Get
End PropertyPublic Sub New(ByVal theUserCtrlInfoPack As UserCtrlInfoPack, ByVal DoGetCountOnly As Boolean)
mUserCtrlInfoPack = theUserCtrlInfoPack
mDoGetCountOnly = DoGetCountOnly
mSuccess = True
End SubProtected Overrides Sub DataPortal_Execute()
Dim theSPMSForm As SPMSForm = Nothing
Dim theStaffID As String
Dim theReviewFrom As String
Dim theMsg As String
Using cn As New SqlConnection(Database.SPMSFormDB)
cn.Open()
Using cm As SqlCommand = cn.CreateCommand
cm.CommandType = CommandType.StoredProcedure
cm.CommandText = "uspSPMSFormListGetRecVer"
cm.Parameters.AddWithValue("@RecVer", SPMSForm.GetSPMSFormInits.RecordVersion)
mRecordsToBeRefreshedCnt = 0
mRecordsRefreshedCnt = 0
Using da As New SqlDataAdapter(cm)
Using ds As New DataSet
da.Fill(ds)
mRecordsToBeRefreshedCnt = ds.Tables(0).Rows.Count
If Not mDoGetCountOnly Then
For Each theRow As DataRow In ds.Tables(0).Rows
theStaffID = theRow.Item("StaffID")
theReviewFrom = theRow.Item("ReviewFrom")
mUserCtrlInfoPack.SetQueryUser(theStaffID)
Try
theSPMSForm = SPMSForm.GetSPMSForm(cn, mUserCtrlInfoPack, theReviewFrom)
theSPMSForm.SetSubmitActionRefreshDBFlds()
theSPMSForm.SaveForm()
Catch ex As Csla.Validation.ValidationException
mSuccess = False
mMessages.AddRange(theSPMSForm.BrokenRulesCollection.ToArray())
Catch ex As Exception
mSuccess = False
theMsg = _
String.Format(My.Resources.ErrRefreshDBFlds, _
ex.Message, theSPMSForm.GetObjectName(), theSPMSForm.IDStr, _
mUserCtrlInfoPack.AuthUserID)
mMessages.Add(theMsg)
End Try
mRecordsRefreshedCnt += 1
theSPMSForm = Nothing
Next
If mSuccess Then
theMsg = _
String.Format( _
My.Resources.RefreshDBFldsConf, _
SPMSForm.GetSPMSFormInits.GetObjectName(), mRecordsRefreshedCnt.ToString, _
mRecordsToBeRefreshedCnt.ToString)
mMessages.Add(theMsg)
End If
End If
End Using
End Using
End Using
End UsingEnd Sub
End Class
I have yet to test the code above. By the way, this is related to the same post I did before (Progress Bar Implementation with Command Object):
http://forums.lhotka.net/forums/t/11176.aspx
Do you have any comment on this matter?
Side Questions: Is there an easy way to insert VB or C# code in this forum ?
Tarek.
Not knowing how your business object structure is, ther may be some issues with:
mMessages.AddRange(theSPMSForm.BrokenRulesCollection.ToArray())
If theSPMSForm has child objects/lists with broken rules you need to use BusinessRules.GetAllBrokenRules (static method) to
get the broken rules from all nodes - the entire tree - and eventually merge into a list of broken rules.
The ProgressBar implementation is very similar (same programming model) to the BackgroundWorker.
This would not necessarily fit so well with a programming model for command object.
Do you use n-tier (an own application server)?
I haven't used this component myself, but the "simple" solution would be to run the code in "DataPortal_Execute" inside the DoWork method.
Paste code:
I use Productivity Power Tools addin for VS2010 - this allows me to do "HTML Copy" of code.
And IE will paste this into the forum as HTML (Firefox used to allow this but not the latest versions).
Thanks Jonny,
It seems that "BusinessRules.GetAllBrokenRules" is not available in CSLA for .NET 2.0 the one I am using.
Anyway, I don't think I need it, since it is a single level object (but very complex).
I am only concerned about the design of my approach. So seems my appraoch is correct.
Regarding Productivity Power Tools addin, is there one for VS 2005? I am not using VS2010 yet.
Tarek.
Use this one for VS2005 and VS2008. http://copysourceashtml.codeplex.com/
I would prefer to move up to VS2008 or VS2010 anyway (if possible) and use CSLA N2
http://wwws.lhotka.net/cslanet/N2.aspx
This will give you access to nearly all of C# 3.0 syntax - including lambdas and linq2objects when your project targets .NET 2.0 SP1.
Read more about LinqBridge here: http://www.albahari.com/nutshell/linqbridge.aspx
Thanks Jonny,
I'll try to move to VS2008 or VS2010 ASAP.
I installed CopyCourseAsHTML (after closing VS2005) from here:
http://copysourceashtml.codeplex.com/releases/view/31130
When I started VS2005 (under Windows 7), I did not see "Copy as HTML". Also, the Add-in Manager box is empty (nothing was installed).
I know this is off-topic, but I appreciate if some one can help me here.
Tarek.
Oh, many thanks Jonny, now I am able to use CopySourceAsHTML with VS2055.
Here is the latest result (to verify):
1 2 Public Shared Function RefreshDBFields(ByVal theUserCtrlInfoPack As UserCtrlInfoPack, ByVal DoGetCountOnly As Boolean) As RefreshDBFieldsCommand 3 Dim result As RefreshDBFieldsCommand 4 If Not AppSecurity.GetSingleton.IsUserAuthorized(AppSecurity.CodesApp.eHRMD, AppSecurity.CodesActions.RefreshDBFlds, AppSecurity.CodesDataTypes.SPMSForm, theUserCtrlInfoPack) Then 5 Throw New System.Security.SecurityException( _ 6 String.Format( _ 7 My.Resources.NotAuthErrorPrm2, _ 8 theUserCtrlInfoPack.AuthUserID, _ 9 AppSecurity.CodesActions.RefreshDBFlds.ToString, _ 10 SPMSForm.GetSPMSFormInits.GetObjectName, "<all>")) 11 End If 12 result = DataPortal.Execute(Of RefreshDBFieldsCommand)(New RefreshDBFieldsCommand(theUserCtrlInfoPack, DoGetCountOnly)) 13 Return result 14 End Function 15 16 <Serializable()> _ 17 Public Class RefreshDBFieldsCommand 18 Inherits CommandBase 19 20 Private mRecordsToBeRefreshedCnt As Integer 21 Private mRecordsRefreshedCnt As Integer 22 Private mDoGetCountOnly As Boolean 23 Private mRecordVersion As Integer 24 Private mUserCtrlInfoPack As UserCtrlInfoPack 25 Private mMessages As New List(Of String) 26 Private mSuccess As Boolean 27 28 Public ReadOnly Property RecordsToBeRefreshedCnt() As Integer 29 Get 30 Return mRecordsToBeRefreshedCnt 31 End Get 32 End Property 33 34 Public ReadOnly Property RecordsRefreshedCnt() As Integer 35 Get 36 Return mRecordsRefreshedCnt 37 End Get 38 End Property 39 40 Public ReadOnly Property Messages() As String() 41 Get 42 Return mMessages.ToArray() 43 End Get 44 End Property 45 46 Public ReadOnly Property Success() As Boolean 47 Get 48 Return mSuccess 49 End Get 50 End Property 51 52 Public Sub New(ByVal theUserCtrlInfoPack As UserCtrlInfoPack, ByVal DoGetCountOnly As Boolean) 53 mUserCtrlInfoPack = theUserCtrlInfoPack 54 mDoGetCountOnly = DoGetCountOnly 55 mSuccess = True 56 End Sub 57 58 Protected Overrides Sub DataPortal_Execute() 59 Dim theSPMSForm As SPMSForm = Nothing 60 Dim theStaffID As String 61 Dim theReviewFrom As String 62 Dim theMsg As String 63 Using cn As New SqlConnection(Database.SPMSFormDB) 64 cn.Open() 65 Using cm As SqlCommand = cn.CreateCommand 66 cm.CommandType = CommandType.StoredProcedure 67 cm.CommandText = "uspSPMSFormListGetRecVer" 68 cm.Parameters.AddWithValue("@RecVer", SPMSForm.GetSPMSFormInits.RecordVersion) 69 mRecordsToBeRefreshedCnt = 0 70 mRecordsRefreshedCnt = 0 71 Using da As New SqlDataAdapter(cm) 72 Using ds As New DataSet 73 da.Fill(ds) 74 mRecordsToBeRefreshedCnt = ds.Tables(0).Rows.Count 75 If Not mDoGetCountOnly Then 76 For Each theRow As DataRow In ds.Tables(0).Rows 77 theStaffID = theRow.Item("StaffID") 78 theReviewFrom = theRow.Item("ReviewFrom") 79 mUserCtrlInfoPack.SetQueryUser(theStaffID) 80 Try 81 theSPMSForm = SPMSForm.GetSPMSForm(cn, mUserCtrlInfoPack, theReviewFrom) 82 theSPMSForm.SetSubmitActionRefreshDBFlds() 83 theSPMSForm.SaveForm() 84 Catch ex As Csla.Validation.ValidationException 85 mSuccess = False 86 mMessages.AddRange(theSPMSForm.BrokenRulesCollection.ToArray()) 87 Catch ex As Exception 88 mSuccess = False 89 theMsg = _ 90 String.Format(My.Resources.ErrRefreshDBFlds, _ 91 ex.Message, theSPMSForm.GetObjectName(), theSPMSForm.IDStr, _ 92 mUserCtrlInfoPack.AuthUserID) 93 mMessages.Add(theMsg) 94 End Try 95 mRecordsRefreshedCnt += 1 96 theSPMSForm = Nothing 97 Next 98 If mSuccess Then 99 theMsg = _ 100 String.Format( _ 101 My.Resources.RefreshDBFldsConf, _ 102 SPMSForm.GetSPMSFormInits.GetObjectName(), mRecordsRefreshedCnt.ToString, _ 103 mRecordsToBeRefreshedCnt.ToString) 104 mMessages.Add(theMsg) 105 End If 106 End If 107 End Using 108 End Using 109 End Using 110 End Using 111 112 End Sub 113 End Class
Much better !
Copyright (c) Marimer LLC