Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Nov 10, 2009 @ 17:15
    Sebastiaan Janssen
    0

    Using ProfileProvider during registration

    I've read the excellent article by Aaron about using a custom ProfileProvider. This is all good and well and works as advertised. 

    However, I am trying to fill the properties during the registration and it is not working. When I save the user, the custom profile fields get set properly, using the custom class MemberProfile, like in Aaron's example. 

    I then save the profile, but when I go into the Umbraco backoffice, I don't see the property being filled.

    This is what I have so far.

    MemberRegister.ascx

    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MemberRegister.ascx.cs" Inherits="Omega.Membership.MemberRegister" %>
    
    <form id="Form1" runat="server" oncreateduser="CreatedUser">
    <asp:CreateUserWizard ID="CreateUserWizard1" runat="server" OnCreatedUser="CreatedUser">
        <WizardSteps>
            <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server">
                <ContentTemplate>
    
                    <asp:Label Text="Last name:" runat="server" ID="lastnameLabel" />
                    <asp:TextBox runat="server" ID="lastname" /><br />
    
                    <asp:Label Text="Username:" runat="server" ID="usernameLabel" />
                    <asp:TextBox runat="server" ID="username" /><br />
    
                    <asp:Label Text="Password:" runat="server" ID="passwordLabel" />
                    <asp:TextBox runat="server" ID="password" /><br />
    
                    <asp:Label Text="E-mail:" runat="server" ID="emailLabel" />
                    <asp:TextBox runat="server" ID="email" /><br />
    
                </ContentTemplate>
            </asp:CreateUserWizardStep>
            <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server">
            </asp:CompleteWizardStep>
        </WizardSteps>
    </asp:CreateUserWizard>
    </form>
    

    MemberRegister.ascx.cs:

    using System;
    using System.Web.UI.WebControls;
    
    namespace Omega.Membership
    {
        public partial class MemberRegister : System.Web.UI.UserControl
        {
            protected void CreatedUser(Object sender, EventArgs e)
            {
                TextBox username = (TextBox)CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("username");
                TextBox lastname = (TextBox)CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("lastname");
    
                var profile = ((MemberProfile) Context.Profile);
                profile.Initialize(username.Text, true);
                profile.LastName = lastname.Text;
                (Context.Profile).Save();
            }
        }
    }

    It seems that the .Save(); does not save the profile values to Umbraco. I can see in my watch that the "profile" has a "lastname" property that is actually filled.

    When I do fill the "lastname" in the Umbraco backoffice and do something like this, the lastname doesn't show up either: 

    using System;
    using System.Web.UI.WebControls;
    
    namespace Omega.Membership
    {
        public partial class MemberRegister : System.Web.UI.UserControl
        {
            protected void Page_Load(Object sender, EventArgs e)
            {
                var profile = ((MemberProfile)Context.Profile);
                profile.Initialize("test22", true);
    
                Response.Write(profile.LastName);
            }
         }
    }

    I must be missing something obvious..?

  • Tim 225 posts 690 karma points
    Nov 12, 2009 @ 18:20
    Tim
    0

    Did you find any joy with this as I am also experiencing the same problem?

    Tim

  • Tim 225 posts 690 karma points
    Nov 12, 2009 @ 18:37
    Tim
    0

    As a temporary work around I'm overriding the Save() method of the ProfileBase class.

    Something like this, this is proof of concept code (not production).

    using System;
    using System.Web.Profile;
    using umbraco.cms.businesslogic.member;
    
    namespace cogworks.incisive.providers
    {
        public class MemberProfile : ProfileBase
        {
            public override void Save()
            {
                base.Save();
                var members = Member.GetMemberByName(UserName,false);
                var member = members[0];
                member.getProperty("favouriteColour").Value = FavouriteColour;
                member.Save();
            }
    
            [SettingsAllowAnonymous(false)]
            public string FavouriteColour
            {
                get
                {
                    var propertyValue = GetPropertyValue("favouriteColour");
                    return propertyValue == DBNull.Value ? "" : (string) propertyValue;
                }
                set
                {
                    SetPropertyValue("favouriteColour", value);
                }
            }
        }
    }

    Tim

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    Nov 13, 2009 @ 09:26
    Sebastiaan Janssen
    0

    @Tim well yeah, but that defeats the whole purpose. I have since had to stop working on membership to implement some higher priority features, but will get back to this problem next week.

    It seems that I'll have to go the API route like you did here, but ditch the profile provider completely as well. Shame, I wish I knew more about this subject so I could create a working implementation and share it.

    Thanks for your reply though!

  • Aaron Powell 1708 posts 3046 karma points c-trib
    Nov 13, 2009 @ 12:34
    Aaron Powell
    0

    I'd assume that you've got your web.config set up as I described it in the post? I'm not overly sure that you need to call the Save method, the setter for the profile properties should invoke the saving against the Member in the Umbraco database.

    If someone's got a sample app which I can play with I'm happy to have a step through the full source tree and see I can work out whether it's a core bug or not.

  • Tim 225 posts 690 karma points
    Nov 13, 2009 @ 14:41
    Tim
    0

    Hi Slace,

    My web.config is not exactly as you have specified.

    I do not have the <properties> element, when this is present I get the following error: "This profile property has already been defined"

    Removing the <properties> element seems to fix this, but of course this may be the problem...

    Tim

     

     

  • Aaron Powell 1708 posts 3046 karma points c-trib
    Nov 13, 2009 @ 22:05
    Aaron Powell
    0

    Yeah I think that's contributing to the problem Tim. The properties element defines how the Umbraco aliases are mapped, and which provider they are mapped to (since you can have properties coming from different providers).

    It could be that since that's not defined it doesn't know how to save the data.

  • Tim 225 posts 690 karma points
    Nov 14, 2009 @ 13:06
    Tim
    0

    OK,

    I've fixed the This profile property has already been defined error (I'd set the property to the name of the property in the MemberProfile class rather than the name of the property - oops!)

    However I discovered another issue which again may be related to my implementation.

    Basically whether then property saves or not seems to depend on how it is called.

    Example 1 (this saves correctly):

    ((MemberProfile)HttpContext.Current.Profile).FavouriteColour = "Blue"

    Example 2 (this does not save correctly):

    var memberProfile = ProfileBase.Create("test");
    memberProfile.FavouriteColour = "Yellow";

    However by adding an invocation of the Save() method in the set method of the property the example above can be also made to save see below: (This saves whichever way it is instantiated)

    using System;
    using System.Web.Profile;
    using System.Web.Security;
    using umbraco.cms.businesslogic.member;
    
    namespace cogworks.providers
    {
        public class MemberProfile : ProfileBase
        {
            [SettingsAllowAnonymous(false)]
            public string FavouriteColour
            {
                get
                {
                    var propertyValue = GetPropertyValue("favourite_colour");
                    return propertyValue == DBNull.Value ? "" : (string) propertyValue;
                }
                set
                {
                    SetPropertyValue("favourite_colour", value);
                    Save();
                }
            }
        }
    }

     

    So for now I'm just adding Save(); alls to my profile properties.

    Tim

  • Emil Badh 8 posts 29 karma points
    Nov 27, 2009 @ 15:27
    Emil Badh
    1

    If your data source is a database and you do multiple changes to a profile at the same time you might want to consider calling Save() from where you are doing the editing (such as a profile page) instead.

    Save() checks all properties to see if they're changed and then saves the to the database. If you are changing ten properties you will perform ten checks, and more important, ten individual updates to the database...

  • Tim 225 posts 690 karma points
    Dec 03, 2009 @ 19:34
    Tim
    0

    Quite correct Emil.

    A very sensible solution. Although if I set it like this:

    ((MemberProfile)HttpContext.Current.Profile).FavouriteColour = "blue"

    It will do the DB updates individually anyway....

    T

Please Sign in or register to post replies

Write your reply to:

Draft