Welcome to AspAdvice Sign in | Join | Help

Add Profile Items in CreateUserWizard and Recursive FindControl

There's an example in Professional ASP.NET 2.0 that shows how to add a few profile items to a CreateUserWizard.  Unfortunately, it doesn't work in certain cases, specifically when the profile item in question is set to allowAnonymous="false".  When that happens, you will receive this error:

"This property cannot be set for anonymous users."

One fix is to simply set the allowAnonymous flag to true, but if it's not something you want anonymous users to be able to set, that's not ideal.  Another thing that can be tricky is referencing your Textbox (or other web form) controls within the CreateUserWizard.  I'll cover that next.

For the profile issue, the fix is to create a local instance of ProfileCommon, as described in this thread on Updating Profile of Created User.

Walter Wang [MSFT] Writes:

I think you can create and save the profile manually after you created the
user:

    ProfileCommon p = (ProfileCommon) ProfileCommon.Create(username, true);
    p.UserInfo.UserEmail = UserName.Text;
    ...

One thing he leaves out in the ... is this line, which is needed to actually save the profile data:

p.Save();

That works, but what about if your profile item's textbox is inside the CreateUserWizard control?  In that case, you need to get a reference to the textbox (let's call it FullNameTextBox).  One option to do this is to use some code like this:

// get an instance of the FullName textbox from the wizard's controls hierarchy.

TextBox FullNameTextBox = CreateUserWizard1.WizardSteps[0].Controls[0].Controls[0].Controls[0].Controls[0].FindControl("FullName") as TextBox;

if(FullNameTextBox!=null)

{

Profile.FullName = FullNameTextBox.Text;

}

Unfortunately this is some very hard to read, and hard to maintain, code.  It's very brittle.  Wouldn't it be nice if FindControl() actually recursed through the Controls() collection of each control in a hierarchy?  Well, it just so happens that my buddy Ambrose Little has some code that will do just this, which he was nice enough to share with me (and which I'm sharing with you).  Replace the above ugliness with this code (which also includes the ProfileCommon fix):

protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)

{

// get an instance of the FullName textbox from the wizard's controls hierarchy.

TextBox FullNameTextBox = FindControl(CreateUserWizard1, "FullName") as TextBox;

if(FullNameTextBox!=null)

{

ProfileCommon p = (ProfileCommon) ProfileCommon.Create(((CreateUserWizard)sender).UserName, true);

p.FullName = FullNameTextBox.Text;

p.Save();

}

}

You can see that I'm now using the FindControl() method, which is defined at Page level (put it in your BasePage class, or call it statically from some Common class, which is what I'm actually doing).  Here is the code:

/// <summary>

/// Returns a control if one by that name exists in the hierarchy of the controls collection of the start control

/// </summary>

/// <param name="start"></param>

/// <param name="id"></param>

/// <returns></returns>

System.Web.UI.Control FindControl(System.Web.UI.Control start, string id)

{

System.Web.UI.Control foundControl;

if (start != null)

{

foundControl = start.FindControl(id);

if (foundControl != null)

return foundControl;

foreach (Control c in start.Controls)

{

foundControl = FindControl(c, id);

if (foundControl != null)

return foundControl;

}

}

return null;

}

Published Wednesday, August 23, 2006 9:49 PM by ssmith
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Add Profile Items in CreateUserWizard and Recursive FindControl

Umm, you have at least few hundred lines of code in this post as I write this comment. Any chance getting that in VB? <grin> (joke)

-Teemu

Thursday, August 24, 2006 4:18 PM by joteke

# Web Application Project Conversion Tips

I upgraded a major website (Visual Studio Web Site Project) to a Web Application Project on VS2005 SP1

Tuesday, January 23, 2007 5:15 PM by Steven Smith

# Coding Optimization Tip: Avoid Repeated FindControl() Use

In a project I&rsquo;m working on I have a recursive FindControl() which is quite useful for finding

Friday, January 26, 2007 10:47 PM by Steven Smith

# re: Add Profile Items in CreateUserWizard and Recursive FindControl

Just a pedantic point, but you can avoid recursion in that routine with a System.Collections.Generic.Stack<Control>, a-la:

           public static Control FindControlRecursive(Control Container, string ID)

           {

               Control ctl = Container.FindControl(ID);

               if (ctl != null)

                   return ctl;

               Stack<Control> ctlStack = new Stack<Control>();

               for (int i = 0; i< Container.Controls.Count;i++)

               {

                   ctlStack.Push(Container.Controls[i]);

               }

               while (ctlStack.Count > 0)

               {

                   ctl = ctlStack.Pop();

                   if (ctl.FindControl(ID) != null)

                       return ctl.FindControl(ID);

                   else

                   {

                       if (ctl.HasControls())

                       {

                           for (int i = 0; i < ctl.Controls.Count; i++)

                           {

                               ctlStack.Push(ctl.Controls[i]);

                           }

                       }

                   }

               }

               return null;

           }

Monday, April 09, 2007 10:31 AM by Paul

# Recursive FindControl<T>

Need to find a control anywhere on the page or in a template? Inspired by Steve Smith&#39;s implementation

Friday, April 13, 2007 4:13 PM by J. Michael Palermo IV

# Recursive FindContol (Of T As Control)

I just posted code to allow recursive search for a control anywhere on the page. Here is the VB (Visual

Friday, April 13, 2007 4:17 PM by J. Michael Palermo IV

# re: Add Profile Items in CreateUserWizard and Recursive FindControl

I simplified J. Michaels code here:

http://intrepidnoodle.com/blog/show/18.aspx

Monday, April 16, 2007 12:02 PM by Aaron

# Recursive FindControl(Of T As Control)

Monday, April 23, 2007 2:27 AM by SteelePrice.Net

# Recursive FindControl(Of T As Control)

Monday, April 23, 2007 2:45 AM by SteelePrice.Net

# re: Add Profile Items in CreateUserWizard and Recursive FindControl

my VB version

Partial Class Default4

   Inherits System.Web.UI.Page

   Public Overloads Function FindControl(Of T As Control)(ByVal id As String) As T

       Return FindChildControl(Of T)(Page, id)

   End Function

   Public Overloads Function FindControl(Of T As Control)(ByVal startingControl As Control, ByVal id As String) As T

       Return ControlFinder.FindControl(Of T)(startingControl, id)

   End Function

   Public Function FindChildControl(Of T As Control)(ByVal startingControl As Control, ByVal id As String) As T

       Return ControlFinder.FindChildControl(Of T)(startingControl, id)

   End Function

   Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

       Me.FindControl(Of RadioButton)(Page, "RadioButton1").Checked = True

   End Sub

End Class

Public NotInheritable Class ControlFinder

   Private Sub New()

       MyBase.New()

   End Sub

   Public Shared Function FindControl(Of T As Control)(ByVal startingControl As Control, ByVal id As String) As T

       Dim found As T = TryCast(startingControl.FindControl(id), T)

       If found Is Nothing Then

           found = FindChildControl(Of T)(startingControl, id)

       End If

       Return found

   End Function

   Public Shared Function FindChildControl(Of T As Control)(ByVal startingControl As Control, ByVal id As String) As T

       Dim found As T = Nothing

       For Each activeControl As Control In startingControl.Controls

           found = TryCast(activeControl, T)

           If found Is Nothing OrElse (String.Compare(id, found.ID, True) <> 0) Then

               found = FindChildControl(Of T)(activeControl, id)

           End If

           If found IsNot Nothing Then

               Exit For

           End If

       Next

       Return found

   End Function

End Class

Thursday, June 21, 2007 2:44 AM by dotnetnoobie

# FIX: LoginView Has No Child Controls

We ran into this issue today: A LoginView control that has always worked just fine was failing to have

Tuesday, August 07, 2007 2:54 PM by Steven Smith

# re: Add Profile Items in CreateUserWizard and Recursive FindControl

magic

Thursday, September 27, 2007 11:40 AM by Ian

# re: Add Profile Items in CreateUserWizard and Recursive FindControl

I love you....

Monday, November 26, 2007 12:37 PM by Ross

# Three Requests for ASP.NET 4 and VS 2010

I have three things that have been on my wish list for ASP.NET and/or Visual Studio that I'm curious

Sunday, March 16, 2008 4:24 PM by Steven Smith

Leave a Comment

(required) 
required 
(required) 
Enter the code you see below