Adding UpdatedBy to Business Objects

Adding UpdatedBy to Business Objects

Old forum URL: forums.lhotka.net/forums/t/5124.aspx


Warren posted on Friday, July 18, 2008

All users of my winform SQL Server app connect to the database via a single SQL Server
userid. Each user is assigned an application userid and role based on their Windows logon which
is authenticated via LDAP.

This has been working real well and management approves because I have locked down the
database to sproc access only for the single SQL Server userid yet authentication is
achieved against the each user's Windows userid, I don't store passwords in the application database.

My issue now is how to best populate the updatedby column in the database tables.  I cannot
use the SQL Server SUSER_NAME() in my sprocs since it returns the database connected user and I need my application user.

I have read another post where the writer suggested their approach would be a shared function
on the Identity object which returns the user name and then provides this to the Save method et al?

Any others care to share how they have done this sort of thing?

Thanks in advance.

rsbaker0 replied on Friday, July 18, 2008

The Csla.ApplicationContext.User contains the current user and identity, so you can just grab this right when saving your object when appropriate. I'm doing this now for our similar auditing requirement.

Another possibility, from our legacy application, is that we have the capability to store the current user in a temporary table in the database that maintains separate data for each connection. Then you can record the update in your stored procedure or trigger. However, this requires that you maintain the value in the database temporary table. (Easy in old-style application that opens and holds the connection for the duration for the application session, more involved in a web or connection sharing situation)

JoeFallon1 replied on Monday, July 21, 2008

The Identity carries the information you need and is available on both sides of the DataPortal.

All you need to do is use it.

So for a SQL statement that saves a new record you might have something like:

Public Function Insert(ByVal code As String, ByVal name As String, ByVal userid As Integer) As String

And when you call the function you pass:

mBO.code, mBO.name, user.userid

Joe


  

Fintanv replied on Monday, July 21, 2008

In the past I have 'overloaded' the workstation id connection string parameter to hold the identity of the user accessing the database.  Take a look at: http://articles.techrepublic.com.com/5100-10878_11-6084879.html for information on the parameters you can add to the connection string.

Regards,
Fintan

Warren replied on Monday, July 21, 2008

I use CSLAGen and this is quite simple to do.

1) Add a function like the following:

Public Module Helpers

' Get the Username of the current user from the CSLA Identity Object
Public Function GetUserName() As String
   Return Csla.ApplicationContext.User.Identity.Name
End Function

End Module

In the CSLAGen value properties for the business object, just set the default to GetUserName().

Thanks for all the great feedback everyone!

JimStone replied on Monday, August 04, 2008

I have a completely local Windows client app.  The UI, BO, and db are all on my PC.

Csla.ApplicationContext.User returns a GenericIdentity and Csla.ApplicationContext.User.Name is an empty string.

I know I am logged on.  What am I missing?  Do I have to set the principal somewhere?

Jim

SonOfPirate replied on Tuesday, August 05, 2008

You have to manually set the Csla.ApplicationContext.User property to the appropriate Principal object.  This is typically done when the app starts.  With single sign-on (i.e. Windows authentication), you'll just grab to the Threading.CurrentPrincipal and use that.

Back to the original question...  In the first post, Warren indicated that:

Each user is assigned an application userid and role based on their Windows login which is authenticated via LDAP.

This is basically the way we do it.  We have our custom "User" object, which implements IPrincipal, exposes the UserID guid property.  We then set this object to Csla.ApplicationContext.User.  In our business objects, before posting to the database (insert/update), we type check the AppContext.User to make sure it is our User object and, if so, use the UserID property to set the LastModifiedBy value.

HTH

 

tiago replied on Wednesday, May 06, 2009

I use AppUser.UserID from the code in http://forums.lhotka.net/forums/thread/28161.aspx

On the DataPortal_Update() I have

_lastChangedBy = AppUser.UserID;
...
cmd.Parameters.AddWithValue("@LastChangedBy", _lastChangedBy);
...

Copyright (c) Marimer LLC