Wednesday, May 7, 2008

ProfileCommon in WebApps fixed quite easily with no addins required

In my previous post, I was sort of happy to see an update for WebProfile for use in VS08.  The thing is, I really dislike the error you get in the build with this approach, I just can't use that in a production environment.  So... I did some more digging and came across this solution by Jon Galloway.  You should read his article for a full explanation of what is going on.

His samples are in C# which is great, but there are some caveats to doing it in VB.

Here is the same code in VB:

 

    Public Class UserProfile         Inherits ProfileBase          Public Shared Function GetUserProfile(ByVal username As String) As UserProfile             Return CType(Create(username), ProfileBase)         End Function          Public Shared Function GetUserProfile() As UserProfile             Return CType(Create(Membership.GetUser().UserName), ProfileBase)         End Function          <SettingsAllowAnonymous(False)> _         Public Property Description() As String             Get                 Return TryCast(MyBase.GetPropertyValue("Description"), String)             End Get             Set(ByVal value As String)                 MyBase.SetPropertyValue("Description", value)             End Set         End Property          <SettingsAllowAnonymous(False)> _         Public Property Location() As String             Get                 Return TryCast(MyBase.GetPropertyValue("Location"), String)             End Get             Set(ByVal value As String)                 MyBase.SetPropertyValue("Location", value)             End Set         End Property          <SettingsAllowAnonymous(False)> _         Public Property FavoriteMovie() As Integer             Get                 Return CInt(MyBase.GetPropertyValue("FavoriteMovie"))             End Get             Set(ByVal value As Integer)                 MyBase.SetPropertyValue("FavoriteMovie", value)             End Set         End Property     End Class 

When using this approach in VB, I still get some occasional errors in the designer when using SplitView, a recompile makes these go away and the code does indeed run fine.  It seems to be something in the background compiler... I wish Microsoft would fix this silly 4 year old bug.

Anyway, I really like this approach MUCH better than placing the profile data in web.config.  If you are relying on the code and some genius decides to add a field or change the name it will cause any dependent code to go haywire anyway when the CodeSpit is regenerated.

When I am controlling the Fields in Code (where it should be anyway...) That is not a major concern since we know what we are doing when the code changes and its not in an editable file by someone not actually Testing the code.

Therefore, all the other methods have many problems that just aren't worth dealing with when this is simple, elegant, effective and safe.

I also find it much easier to just use an instance rather than some other suggestions of using a Property in a BasePage. 

i.e

Dim prof = UserProfile.GetUserProfile()
or
Dim prof = UserProfile.GetUserProfile(username)

I also found that turning off Automatic updates seems to help with the errors for some reason, with it turned off, I don't seem to get them any more and thus you need to do your saves with an instance or you will have to perform a save after changing any item since getuserprofile will overwrite any unwritten changes to the object because it is creating a new instance every time.

So my resulting web.config looks like this:

<profile automaticSaveEnabled="false"
           enabled="true"
           inherits="ProfileUtility.UserProfile">

This is for the Default Provider, if you use  Custom Provider as well, use the following:

<profile defaultProvider="<YourProviderName>"
           automaticSaveEnabled="false"
           enabled="true"
           inherits="MonetaModel.UserProfile">