Small Template Changes (VB.net 3.5 )

18 views
Skip to first unread message

pandelis

unread,
Sep 22, 2009, 1:01:21 PM9/22/09
to CslaGenerator
I made some changes to some templates that didnt work on me and on
CSLA 3.7.
Readonlycollection is created using InternalGetObject.inc and when
combined with authorization it uses this line of code

<% If Info.GetRoles.Trim() <> String.Empty Then %>
If Not CanGetObject() Then
Throw New System.Security.SecurityException( _
"User not authorized to load a <%= Info.ObjectName %>")
End If
<% End If %>

CanGetObject() didnt worked for me.

<% If Info.GetRoles.Trim() <> String.Empty Then %>
If Not Csla.Security.AuthorizationRules.CanGetObject(GetType(<
%=Info.ObjectName%>)) Then
Throw New System.Security.SecurityException( _
"User not authorized to load a <%= Info.ObjectName %>")
End If
<% End If %>

this one worked fine :)

i also added some lines to SharedAuthorizationMethods.inc so that
authorizations rules, other than fetch, wont be created on
readonlyobjects (cant be deleted, updated, or inserted anyway!)

ill give u an example with delete authorization

<% If Info.DeleteRoles.Trim() <> String.Empty and Info.ObjectType =
CslaObjectType.ReadOnlyObject Then %>
<% If Info.ObjectType = CslaObjectType.ReadOnlyObject or
Info.ObjectType = CslaObjectType.ReadOnlyCollection Then %>
<% Else %>
Csla.Security.AuthorizationRules.AllowEdit(GetType(<%= Info.ObjectName
%>)<%
Dim roles() As String = System.Text.RegularExpressions.Regex.Split
(Info.UpdateRoles, ";")
For Each role As String In roles %>, "<%= role %>"<% Next %>)
<% End If %>
<% End If %>

this one isnt really useful if u r smart enough not to add roles just
everywhere, but still useful for me :)

pandelis

unread,
Sep 22, 2009, 1:09:48 PM9/22/09
to CslaGenerator
Also had the Cangetobject problem on NameValueLists

Andrés Villanueva

unread,
Sep 22, 2009, 1:10:07 PM9/22/09
to cslage...@googlegroups.com
Hi Pandelis!
Thanks for reporting it. It had already been brought to my attention and it's queued up for next release.
It's been a while since last release and not many bugs have been reported, so I might make a new release soon with just those small template fixes.
If there's anybody holding back on reporting other bugs please let me know so we can have them fixed for next release!!
--
Andrés

pandelis

unread,
Sep 23, 2009, 1:19:32 AM9/23/09
to CslaGenerator
now that u mention it i am trying to fix an issue with private managed
backing field properties and editableobjects that include one or many
editablechildcollections. The setter of the property isnt generated
properly.

Andrés Villanueva

unread,
Sep 23, 2009, 9:53:10 AM9/23/09
to cslage...@googlegroups.com
Can you give me an example?
--
Andrés

pandelis

unread,
Sep 23, 2009, 11:01:10 AM9/23/09
to CslaGenerator
I have CSLAGEN set to csla35 , VB and managedbackingfield property
mode. Then i create an editable root object (ER) with a child
collection property set to an editable child collection(ECC). The
resulting property of the ER concerning the ECC comes out to be
managed, not having a managedbackingfield, and the setter part seems
to be standard, rather than the expected.

Set (value As ECC)
MyECC = value
End Set


that one should be sth like that

Set (value As ECC)
SetProperty(MyECCProperty, value)
End Set

I modified the template to give the desired result although i didnt
fix the backingfield issue yet.(since it works i dont mind :))

line 126 BusinessProps.inc

<% If Info.ObjectType <> CslaObjectType.ReadOnlyObject AndAlso
prop.ReadOnly = False Then %>
<% If _child.ObjectType = CslaObjectType.editablechildcollection or
_child.ObjectType = CslaObjectType.editablechild Then %>
Set (byval value As <%=prop.TypeName%>)
SetProperty(<%=FormatManaged(prop.Name)%>, value)
End Set
<% else %>
Set (value As <%=prop.TypeName%>)
<%=FormatFieldName(prop.Name)%> = value
End Set
<% End If %>
<% End If %>


Managedbackingfield properties are a bit faster than simple managed
properties right? Thats the main reason i am using these and
discussing the matter.

Another questions is why do state fields come out protected and not
private?

pandelis

unread,
Sep 23, 2009, 11:04:45 AM9/23/09
to CslaGenerator
How about property authorization ? Do u think this is sth u can
include in CSLAgen easily? I am not eager on using it soon, just
asking.

pandelis

unread,
Sep 23, 2009, 11:08:43 AM9/23/09
to CslaGenerator
forgot one byval . the correct should be :

<% If Info.ObjectType <> CslaObjectType.ReadOnlyObject AndAlso
prop.ReadOnly = False Then %>
<% If _child.ObjectType =
CslaObjectType.editablechildcollection or
_child.ObjectType = CslaObjectType.editablechild Then %>
Set (byval value As <%=prop.TypeName%>)
SetProperty(<%=FormatManaged(prop.Name)%>,
value)
End Set
<% else %>
Set (byval value As <%=prop.TypeName%>)

Andrés Villanueva

unread,
Sep 23, 2009, 11:17:15 AM9/23/09
to cslage...@googlegroups.com
OK, in 3.x child objects are always managed. It's the preferred method now because of how the dataportal works and has several benefits... not requiring to override isvalid, isdirty, getting Child_Changed events automatically, SetParent called automatically are the ones that come to mind right now.
So, for those reasons, child objects are ALWAYS managed for 3.x.

The set piece is probably a bug, since child objects should never have a setter, but if you're seeing that it's probably because the child object is set as readonly = false. Set it back to true and the setter will go away (I'll fix this so that it never has a setter regardless of that setting).

The protected modifier is just heritage. There's no specific reason.

And yes, property auth is definitely something I plan to add.
--
Andrés

pandelis

unread,
Sep 23, 2009, 12:08:36 PM9/23/09
to CslaGenerator
just wondering here on a matter discussed above. I used this ""
Csla.Security.AuthorizationRules.CanGetObject(GetType(MYObject)) "" to
get to know whether i can get my object or not. Wouldn't it be better
in the old fashioned way? having the cangetobject function?

Public Shared Function CanGetObject() As Boolean

Return Return Csla.ApplicationContext.User.IsInRole
("ProjectManager")

End Function

Andrés Villanueva

unread,
Sep 23, 2009, 12:18:04 PM9/23/09
to cslage...@googlegroups.com
I think you don't need to do either. If I recall correctly, the dataportal enforces that (correct me if I'm wrong). All we need to do is remove that piece of code. Either way, the old method is no longer valid.
--
Andrés

pandelis

unread,
Sep 24, 2009, 1:26:33 AM9/24/09
to CslaGenerator
you are correct Andres. Indeed the dataportal enforces that. Thank you
for your time.

pandelis

unread,
Sep 28, 2009, 4:51:41 AM9/28/09
to CslaGenerator
I am not sure if this is my mistake, but when u add an
EditableChildObject (not list) inside an editable root object the
following code isnt generated inside DataPortal_Update and
DataPortal_Insert

If FieldManager.FieldExists(MYECL_Property) Then
DataPortal.UpdateChild(ReadProperty(MYECL)(MYECLProperty), Me)
End If

pandelis

unread,
Sep 28, 2009, 6:15:24 AM9/28/09
to CslaGenerator
even if i do add the DataPortal.UpdateChild method still nothing
happens on the child object. The problem should be somewhere else.
Lists have no problem by the way on the same scenario.

Andrés Villanueva

unread,
Sep 28, 2009, 7:35:47 AM9/28/09
to cslage...@googlegroups.com
Yep, that's another bug.
UpdateChildProperties.inc, line 4:
Change GetCollectionChildProperties for GetAllChildProperties.

Not sure about the other problem though.
--
Andrés

pandelis

unread,
Sep 28, 2009, 10:49:40 AM9/28/09
to CslaGenerator
it seems the other bug is mine alone :) i have a complex databinding
scenario with 2 similar root objects having editable child objects
that react differently. So no worries on the second one :)

Andrés Villanueva

unread,
Sep 28, 2009, 11:06:31 AM9/28/09
to cslage...@googlegroups.com
Glad to hear you solved it. Thanks for all your feedback!
--
Andrés

pandelis

unread,
Sep 29, 2009, 1:38:38 AM9/29/09
to CslaGenerator
Sorry Adres but i found a new problem! Its in Editable Root List. All
is well but one thing. The main list doesn't override
Dataportal_Update, which means that you never get to the desired
child_update , child_insert. In fact i followed this link to find out
whats happening myself cause the book instructed otherwise or i simply
misunderstood.

http://forums.lhotka.net/forums/thread/30352.aspx

Also if possible add the AddNewCore ovveride for each EditableRootList
as almost all of them needs them. Or we could try to create a plugin
for that part.

pandelis

unread,
Sep 29, 2009, 1:44:31 AM9/29/09
to CslaGenerator
I was incorrect in saying that u dont override the method! The proper
code isnt used though!

MyBase.DataPortal_Update() should be changed to

Child_Update()

Wouldn't it be better to use the following code in between the
update?

Me.RaiseListChangedEvents = False

Me.RaiseListChangedEvents = true

pandelis

unread,
Sep 29, 2009, 3:41:29 AM9/29/09
to CslaGenerator
oh another suggestion i would like to make concerns namevaluelists.
Eventually u end up wanting to delete sth from a field that a
namevaluelist is bound to. In that scenario (at least thats what i
do), in order not to break binding and stuff, i end up creating an
empty or zero namevaluepair (depending on the default for each key and
value) entry in the namevaluelist which the user can choose for an
empty field. If u think thats a common scenario maybe in the next
update there could be done sth about that also. I am lazy, am i not? :)

pandelis

unread,
Sep 29, 2009, 4:02:49 AM9/29/09
to CslaGenerator
Another problem i faced with EditableRootLists is:

the generator creates a method for the creation of a new ERL without
having any criteria objects. The result is that the NEW_ERL method is
correct but it creates no subsequent override for the
dataportal_create . Maybe a default criteriaNEW should be created
everytime we make an ERL?

pandelis

unread,
Sep 29, 2009, 5:03:48 AM9/29/09
to CslaGenerator
to partially fix the problem i added this to the data access region of
EditableRootCollection.cst

<!-- #include file="DataPortalCreate.inc" -->

i also added that to the end of DataPortalCreate.inc

<% If Info.ObjectType = CslaObjectType.EditableRootCollection Then %>
''' <summary>
''' Load default values for the <see cref="<%=Info.ObjectName%>" />
object's properties from the database.
''' </summary>
<CSLA.RunLocal()> _
Protected Overloads Sub DataPortal_Create()
End Sub
<% End If %>

pandelis

unread,
Sep 29, 2009, 5:40:31 AM9/29/09
to CslaGenerator
Maybe i overdid it a bit, but i am on the process of upgrading a
rather big project and i thought someone might face the same problems.
This is also a great project that needs the support of everyone of us,
since we are quite few.

Anyway, another problem i had since the previous version was with the
DataPortal_Delete function within EditableRootObject. There are 2
overloaded procedures but they end up having the same procedure name
by default so the first function cant be called properly. Also only
one SP is created in the sql file!

Bill Larman

unread,
Sep 29, 2009, 7:08:30 AM9/29/09
to cslage...@googlegroups.com
Have a look at the criteria.
There will be 2 criteria (Criteria, CriteriaTS) with the DeleteOptions set to true.
The Criteria one just uses the PK to delete and the CriteriaTS used the PK and also the TimeStamp.
Set the one you don't want to use to DeleteOptions False.
 
In my case I always set the CriteriaTS DeleteOptions to False as I don't care what the TimeStamp is when deleting.
I only use the CriteiaTS for Updating when I need to know if someone else has updated the object whilst I was editing.
 
Regards,
 
Bill
 
> Date: Tue, 29 Sep 2009 02:40:31 -0700
> Subject: Re: Small Template Changes (VB.net 3.5 )
> From: pande...@yahoo.com
> To: cslage...@googlegroups.com

Andrés Villanueva

unread,
Sep 29, 2009, 9:14:45 AM9/29/09
to cslage...@googlegroups.com
OK:
-Editable Root List: We don't need to override dataportal_update anymore, the base class handles this for you. If the Editable Root List is still overriding that, it needs to go away. Is Dataportal_Create() required? does it crash if it isn't there?
-AddNewCore: I don't override this on purpose. The criteria for create new may contain parameters that aren't necesarily the same for every case. Letting you do those 3 lines gives you total control, and if you don't need anything special, it's still 3 simple lines. I can change my mind about that if there's a good reason though...
-Delete procedures: Look at the criteria objects (Delete options). Add a suffix or rename the SP. Set Procedure to True for generating that sproc (not recommended if you don't have any params).

For the nvl thing you mention, that's more of a UI thing. Consider doing something like the following. This way, at the moment of binding your dropdownlist you do something like this:

>> SetNVL(ComboBox1, MyNVL.GetMyNVL(), 0, "<Please Select>") '  <--- The "0" is your empty value

=============
    Public Sub SetNVL(ByVal cbo As ComboBox, ByVal nvl As Object)
        SetNVL(cbo, nvl, "Value", "Key")
    End Sub
    Public Sub SetNVL(ByVal cbo As ComboBox, ByVal nvl As Object, ByVal displayMember As String, ByVal valueMember As String)
        cbo.SuspendLayout()
        cbo.DisplayMember = displayMember
        cbo.ValueMember = valueMember
        cbo.DataSource = nvl
        cbo.ResumeLayout()
    End Sub
    Public Sub SetNVLWithDefault(Of T)(ByVal cbo As ComboBox, ByVal nvl As IEnumerable(Of Csla.NameValueListBase(Of T, String).NameValuePair), ByVal defaultId As T, ByVal defaultText As String)
        Dim lst As New List(Of Csla.NameValueListBase(Of T, String).NameValuePair)
        lst.Add(New Csla.NameValueListBase(Of T, String).NameValuePair(defaultId, defaultText))
        lst.AddRange(nvl)
        SetNVL(cbo, lst)
    End Sub

    'Set with default Guid id
    Public Sub SetNVLWithDefault(ByVal cbo As ComboBox, ByVal nvl As IEnumerable(Of Csla.NameValueListBase(Of Guid, String).NameValuePair), ByVal defaultId As Guid, ByVal defaultText As String)
        SetNVLWithDefault(Of Guid)(cbo, nvl, defaultId, defaultText)
    End Sub
    'Set with default Int16 id
    Public Sub SetNVLWithDefault(ByVal cbo As ComboBox, ByVal nvl As IEnumerable(Of Csla.NameValueListBase(Of Int16, String).NameValuePair), ByVal defaultId As Int16, ByVal defaultText As String)
        SetNVLWithDefault(Of Int16)(cbo, nvl, defaultId, defaultText)
    End Sub
    'Set with default Int32 id
    Public Sub SetNVLWithDefault(ByVal cbo As ComboBox, ByVal nvl As IEnumerable(Of Csla.NameValueListBase(Of Integer, String).NameValuePair), ByVal defaultId As Integer, ByVal defaultText As String)
        SetNVLWithDefault(Of Integer)(cbo, nvl, defaultId, defaultText)
    End Sub
    'Set with default Int64 id
    Public Sub SetNVLWithDefault(ByVal cbo As ComboBox, ByVal nvl As IEnumerable(Of Csla.NameValueListBase(Of Int64, String).NameValuePair), ByVal defaultId As Int64, ByVal defaultText As String)
        SetNVLWithDefault(Of Int64)(cbo, nvl, defaultId, defaultText)
    End Sub

==============

I hope I didn¡t miss anything...

--
Andrés

Andrés Villanueva

unread,
Sep 29, 2009, 9:21:36 AM9/29/09
to cslage...@googlegroups.com
My bad, ERC does need a Dataportal_Update. I'll switch to MyBase.Child_Update() (although, it does look wierd....)

2009/9/29 Andrés Villanueva <xal...@gmail.com>



--
Andrés

pandelis

unread,
Sep 29, 2009, 10:24:24 AM9/29/09
to CslaGenerator
Thank you all for the help! Andres the NameValueList solution is
perfect.

As for the dataportal_create it was necessary for me, cause it crashed
without it. After doing what i described above it worked! Although i
am not sure if this is the best approach.

If i remember correctly dataportal_update didnt work for me. Removing
the override didnt work either. All code is properly generated and it
doesnt work unless i override the method to something like this.

Protected Overrides Sub DataPortal_Update()
Me.RaiseListChangedEvents = False
Using ctx = ConnectionManager(Of SqlConnection).GetManager
(Database.MYConnection, False)
Child_Update()
End Using
Me.RaiseListChangedEvents = True
End Sub

I also read the book and i also believed that there was no need for
this. But without it i get no luck in updating anything.

Using << mybase.Dataportal_update >> instead causes a
system.Notsupportedexception.
Reply all
Reply to author
Forward
0 new messages