How to add a Login, Roles and Profile system to an ASP.NET 2.0 app in only 24 lines of code

I’ve seen a few questions in the forums lately looking for examples on how to use the CreateUserWizard control to create new users in the ASP.NET 2.0 membership system, and then as part of the registration process assign the new user into custom roles and/or collect and store custom profile properties about them (country, address, gender, zipcode, etc).

 

Stefan from my team had a cool CreateUserWizard control sample that I borrowed and expanded upon to build-up a sample that demonstrates how to build a fairly common user management, roles and personalization system in ASP.NET 2.0 that does this.  I was pleasantly surprised to find it only took about 25 lines of C# code in the entire app. J

 

The sample comes with 6 pages:

 

 

Specifically it supports:

 

1) Login support to enable registered users to login to the web app using forms auth and the new membership system (login.aspx)

2) Registration support to enable visitors to create and register new users in the membership system (CreateNewWizard.aspx)

3) Profile support that enables the site to gather information about the user on registration, and for the users to see that information on a profile page (MyProfile.aspx). 

4) Change Password support to enable registered users to change their password in the membership system (ChangePassword.aspx)

5) Password Recovery support to enable users to reset their password if they forgot them (RecoverPassword.aspx)

 

You can download and run the sample yourself from here.  Note that it is built with the final release of VS 2005 and ASP.NET 2.0 – so it won’t work with Beta2 (although it will probably work with the RC).

 

Implementation Notes on CreateNewWizard.aspx and MyProfile.aspx:

 

Only two of the above pages (CreateNewWizard.aspx and MyProfile.aspx) have code in them.  The others use the built-in Login controls in V2 to-do everything (asp:login, asp:passwordrecovery, asp:changepassword). 

 

CreateNewWizard.aspx is the most interesting page.  It uses the built-in <asp:createuserwizard> server control to-do most of the heavy lifting and has two templated wizard steps defined within the wizard:

 

<asp:createuserwizard> wizard step 1: gathering user-account data

 

 

The <asp:createuserwizard> control handles gathering up the user-account, email, password, and password recovery/answer data and then calling into the ASP.NET 2.0 membership system to register the new user.  You simply have to override the control’s <createuserwizardstep> template and customize the control layout to have things look how you want. 

 

The sample is using the ASP.NET validation controls to perform client-side validation on the inputs as well within the template (example: making sure passwords match, the age is a valid integer, etc).  One added benefit in ASP.NET 2.0 is that these validation controls now support client-side validation for FireFox and other modern browsers (note: all screenshots were done using FireFox).

 

There are then three additional properties (their country, gender and age) that I wanted to gather up about the new user as part of the registration process.  Doing this was pretty easy using the new ASP.NET 2.0 Profile system – simply add their definitions within the <profile> tag of the web.config file to register them and store their values in the new profile system:

 

<profile enabled="true">

    <properties>

        <add name="Country" type="string"/>

        <add name="Gender" type="string"/>

        <add name="Age" type="Int32"/>

    </properties>

</profile>

 

I then handled the “CreatedUser” event on the CreateUserWizard control within my CreateNewWizard.aspx.cs code-behind file to retrieve the values from the controls within the CreateUserWizard control template and set them in the profile store:

 

// CreatedUser event is called when a new user is successfully created

public void CreateUserWizard1_CreatedUser(object sender, EventArgs e) {

 

   // Create an empty Profile for the newly created user

   ProfileCommon p = (ProfileCommon) ProfileCommon.Create(CreateUserWizard1.UserName, true);

 

   // Populate some Profile properties off of the create user wizard

   p.Country = ((DropDownList)CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("Country")).SelectedValue;

   p.Gender = ((DropDownList)CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("Gender")).SelectedValue;

   p.Age = Int32.Parse(((TextBox)CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("Age")).Text);

 

   // Save profile - must be done since we explicitly created it

   p.Save();

}

 

Because the user is being created as part of this step, I explicitly choose to create a new Profile object in code (note that I was passing in the CreatedUserWizard1.UserName property as the username – since the user isn’t logged into the system yet).  I then accessed the controls within the template of the <asp:createuserwizard> control, pulled out their values, and stuck them within the newly created profile.  Calling p.save at the end registered this profile with the new username.  (note: I’ll walk through how we use this profile data later in a page below).

 

<asp:createuserwizard> wizard step 2: picking roles

 

After the user fills out the first step of registration information and clicks the next button, the user is created, the CreatedUser event fires, and we fill in the appropriate information about the user into the profile store. 

 

The <asp:createuserwizard> control then displays the second step template we’ve defined.  This template lists all of the roles currently created in the ASP.NET Role Management system, and allows the user to select which roles they belong to:

 

 

Note that you’d typically never assign roles to an end-user this way (instead you’d add your own logic to somehow calculate which role they belong in), but I thought this scenario was cool nonetheless which is why it works like the sample above.

 

I think it is cool because of the way we populate and access these roles in the template of the <asp:createuserwizard>.  Basically, we have a template definition to the .aspx like this:

 

<asp:WizardStep runat="server" AllowReturn="False"

                OnActivate="AssignUserToRoles_Activate"             

                OnDeactivate="AssignUserToRoles_Deactivate">

    <table>

        <tr>

           <td>

              Select one or more roles for the user:

           </td>

        </tr>

        <tr>

            <td>

               <asp:ListBox ID="AvailableRoles" runat="server"

                            SelectionMode="Multiple" >

               </asp:ListBox>

            </td>

        </tr>

    </table>

</asp:WizardStep>

 

It simply contains a <asp:listbox> control named “AvailableRoles”.  When this wizard step is loaded (after the user hits the next button on the first step in the wizard), it will fire the “OnActivate” event.  We can use this to databind the list of all roles in the system to the above listbox.  When the user hits next again, the wizard will fire the “OnDeactivate” event.  We can then use this to determine which roles were selected in the above listbox, and use them to update the role-manager system.

 

The code to-do both of these actions looks like this:

 

// Activate event fires when user hits "next" in the CreateUserWizard

public void AssignUserToRoles_Activate(object sender, EventArgs e) {

 

    // Databind list of roles in the role manager system to listbox

    AvailableRoles.DataSource = Roles.GetAllRoles(); ;

    AvailableRoles.DataBind();

}

 

// Deactivate event fires when user hits "next" in the CreateUserWizard

public void AssignUserToRoles_Deactivate(object sender, EventArgs e) {

 

    // Add user to all selected roles from the roles listbox

    for (int i = 0; i < AvailableRoles.Items.Count; i++) {

        if (AvailableRoles.Items[i].Selected == true)

           Roles.AddUserToRole(CreateUserWizard1.UserName, AvailableRoles.Items[i].Value);

    }

}

 

That is all of the code for the CreateNewWizard.aspx.cs file – 17 lines total if you omit comments and whitespace (if my count is right). 

 

Next Step: Displaying User Profile Data

 

The only other page in this scenario that required me to add code was the MyProfile.aspx page.  This page looks like this:

 

 

The page itself was pretty simple to implement.  I simply added a few asp:label controls on the page, as well a listbox for the roles.  Populating these controls with the profile and role information involved added a Page_Load event with 7 lines of code like so:

 

protected void Page_Load(object sender, EventArgs e) {

 

   Country.Text = Profile.Country;

   Gender.Text = Profile.Gender;

   Age.Text = Profile.Age.ToString();

 

   RoleList.DataSource = Roles.GetRolesForUser(User.Identity.Name);

   RoleList.DataBind();

}

 

Note that the profile object is strongly typed – which means profile properties will get statement completion and compilation checking in VS 2005 with it.  I can also then query the role management system to retrieve an array of all the roles the current user belongs to and then databind this to the listbox control. 

 

Since the MyProfile.aspx page requires a user to be logged in (otherwise retrieving profile information about them doesn’t make a lot of sense), I also added a <location> based authorization control tag in my web.config file:

 

<location path="MyProfile.aspx">

     

   <system.web>

      <authorization>

            <deny users="?"/>

            <allow users="*"/>

      </authorization>

   </system.web>

 

</location>

 

This is the same configuration I would have added in ASP.NET V1.1 – and basically tells the system to deny all users who aren’t logged in (the ? = anonymous), and then allow all users who are logged in (the * = all). 

 

Those who aren’t logged in will get automatically re-directed to the login.aspx page.  The <asp:login> control can be used there to allow users who have already registered to log-in without the developer having to write any custom code.

 

Summary

 

Hopefully this walks-through a fairly common real-world web app scenario and explains how it can be easily done in ASP.NET 2.0.  The ASP.NET 2.0 Membership, Role and Profile system (especially when combined with the new login controls) pack a lot of productivity power. 

 

What is really nice is that they are all built on the new ASP.NET 2.0 provider model.  Our of the box ASP.NET ships built-in providers that provide Membership, Roles and Profile storage inside SQL Express, SQL Server and Active Directory stores (the later for Membership and Roles only).  What is even better is that you can replace any of these implementations using a custom provider that you either buy or build yourself (see this blog post for more details on how to-do this).  Replacing a provider in ASP.NET 2.0 simply involves changing a value in a web.config file – the above code sample will work regardless of what provider was plugged in (LDAP, Oracle, DB2, Custom SQL Table Schema, File-System, etc).

 

Hope this helps,

 

Scott

 

133 Comments

  • Speaking of RTM bits being on MSDN, do you know how much longer before we (MSDN subscribers) can get our hands on VS2005 RTM Scott?

  • Hi Dempsey,



    We haven't officially signed off yet on the final bits. I think it will probably be available for MSDN subscribers shortly before launch (but am not 100% sure of the date).



    Hope this helps,



    Scott

  • Hi Scott,



    Thanks for the examples and explanation. I have a question on the remember me checkbox. If the user checks this, will this mean that is logged in automaticly when she revisites the site. Or does a developer has to handle this herself.

  • Hi Henk,



    If the user checks this the Login control will automatically set the forms-auth cookie to be persistant -- so assuming the ticket hasn't expired they will automatically be logged in next time without the developer having to-do anything.



    One caveat in ASP.NET V2.0 is that (for security reasons) the default forms auth ticket length is now a sliding 30 minute window instead of the 50 years it defaulted to in V1.1. If you want to change this (which most people probably will), you can change this in your web.config file as a configuration setting.



    Hope this helps,



    Scott

  • Will you be able to use the Login Controls with your own Database or do you have to allow ASP.Net to do so?



    Thank you,



    Michael



    michael@dorsetwebsolutions.com

  • Hi Michael,



    Yep -- you can use your own databases used if you implement a Membership provider that goes against your database.



    Hope this helps,



    Scott

  • Hi Scott,



    You are getting me excited! Are you saying that all we have to do is to define the custom properties (country, gender and age) in the web.config, the ASP.NET 2.0 Profile system will create the fields in a table inside Aspnetdb? Wow that will be great if true!

  • Hi Jackson,



    Yep -- that is all you need to-do. :-)



    We'll also be shipping another profile provider on the web that will allow you to bind the profile against an already defined database table as well. That way you'll also be able to integrate with existing data and perform even richer queries/updates on them.



    Hope this helps,



    Scott

  • Scott, &quot; profile provider on the web that will allow you to bind the profile against an already defined database table&quot;



    Wow, that's excellent. Currently, in my development, I need to extract it manually to my tables.



    Thanks,

    John

  • Hey there,



    I'm using the Login Controls now the standard way with the SQL Server Express mdf file as storage engine.



    If I'd like to switch to MS-SQL (not express) sometime do I only have to copy all the tables and data to MS-SQL and switch the Provider in the web.config from express to mssql?



    I would just like to go sure I understood everything :o, thanks a lot for your time!

  • Nice, thanks Scott! Everything worked fine.

  • Hi Scott



    This looks cool but am I missing something as the way that the event handlers AssignUserToRoles_Activate and AssignUserToRoles_Deactivate are created seems rather odd



    I am running VS 05 RTM and the only way that I can see to create these is to assign the OnActivate and OnDeactivate property inside the source view of ASPX file and then write the 2 event handlers in the code behind page.



    Nothing shows up anywhere under the Events view in the properties window so it a pain to add this code and it feels like the ASP coding days.



    Should this be parts of the Tasks ?

  • Great summary! this will help me a lot in my SSO project.



    do you have any links on implimenting this with an already existing AD userbase?

  • Hi Mike,



    The wizardtask control I added in the sample is in a templated control -- which makes it hard to get to from the property-grid in design-view.



    If you don't want to-do event wire hookup declaratively (which is what I did in the sample), you can alternatively do it programmatically by adding a Page_Init() event handler in your code-behind. There you can explictly wire them up without having to ever even open the .aspx file:



    public void Page_Init(Object sender, EventArgs e)

    {

    wsAssignUserToRoles.Activate += new EventHandler(AssignUserToRoles_Activate);

    wsAssignUserToRoles.Deactivate += new EventHandler(wsAssignUserToRoles_Deactivate);

    }



    Hope this helps,



    Scott

  • Scott



    Many thanks - that is exactly what I need



    Mike

  • Thank you for your amazing codes.

    I'd like to learn C# to better understand your code and more.



    Could you recommend a beginner's book (Bible) for C# language, especially, I am more interested in web developing in C Sharp.



  • Maybe I am a little late and I am no Scot Gu nor ASP.NET only coder, but my beloved book in 1.0 times was from Jesse Liberty Programming C#, and it was in 4th edition last time I checked covering C#2.0 already.



    It was one awesome book, but there are many more favorites out there(Proffesional ASP.NET 2.0 and Bill Evjen, Jeff Prosise was also my fav author on ASP etc) , but if you like to learn language try this book first, it covers ASP.NET to some extent.

  • Hi All,



    Great thread about the magic functions of membership and role but does anybody have a suggestion to make all the process multilingual ?



    Thanks all

  • This is an awesome example! &nbsp;Do you have a similar example using Visual Basic?

  • Hi Chris,

    Unfortunately I don't have a VB sample yet -- but it is on my list of things todo!

    Thanks,

    Scott

  • Scott -- How does one retrieve information for a given user once on log on, rather than on each page load, and keep that information for the entire session? &nbsp;I was trying to use the LoggedIn event, but was having trouble. Thanks, Robert

  • Hi Robert,

    You could store the information in the session object if you wanted to. You can use the Login control's username property to retrieve it within the LoggedIn event to-do this.

    In general, though, I'd probably recommend just working directly off of the Profile API -- which will fetch the data on demand as needed.

    Hope this helps,

    Scott

  • Can u creat all of them on the code behind? without source?

  • Hi Esra,

    Rather than use controls you could also use the Membership and Roles APIs directly to create users and map them into roles programmatically.

    Hope this helps,

    Scott

  • Hy Scott!



    First, thanks for all you do!



    I have a small problem with the CreateUserWizard. I have the LoginCreatedUser property set to false. I am creating their password initially for them and sending it to them in email to verify their email. I also need to do some other database work when their account is created. I need the user id(guid) that gets created but I dont see an easy place to retrieve that in the createduser event. Any idea how to get it?



    Again, thanks!!

    Brad Coble

  • Hi Brad,

    You should be able to write this code within your CreatedUser event handler:

    MembershipUser mu = Membership.GetUser(CreateUserWizard1.UserName);
    Guid puk = (Guid)mu.ProviderUserKey;

    Hope this helps,

    Scott

  • And how can I remove e-mail from user credentials?

  • Hello Scott, I have successfully created a user file by using SQL Memebership provider and added below lines in my web.config file &lt;profile enabled="true" defaultProvider="AspNetSqlMembershipProvider"&gt; &nbsp; &nbsp; &nbsp;&lt;providers&gt; &nbsp; &nbsp; &nbsp; &nbsp;&lt;add &nbsp;name="AspNetSqlMembershipProvider" &nbsp; &nbsp; &nbsp; &lt;/providers&gt; &nbsp; &nbsp; &nbsp;&lt;properties&gt; &nbsp; &nbsp; &nbsp; &nbsp;&lt;add name="FirstName" type="string" /&gt; &nbsp; &nbsp; &nbsp; &nbsp;&lt;add name="LastName" type="string" /&gt; &nbsp; &nbsp; &nbsp;&lt;/properties&gt; &nbsp; &nbsp;&lt;/profile&gt; First Name &amp; Last Name successfully saved in aspnet_profile table. But I am getting error message when I am trying to retireve user profile. Below is my code ProfileCommon prf = new ProfileCommon(); UserFirstName.Text = prf.FirstName.ToString(); serLastName.Text = prf.LastName.ToString(); and error message is The settings property 'FirstName' was not found. The settings property 'LastName' was not found. Could you please let me know what I am missing. Regards

  • I am trying to create a create account screen based on what you have here. The issue I am facing is I am not able to trap dropdown list box events. I have country dropdown list and upon selecting the Country I would like to populate the state but I am not able to trap the event for dropdown listbox. I am using VB.NET BTW.

  • Hi Adnan,

    Have you tried doing this:

    UserFirstName.Text = Profile.FirstName.ToString();

    Does that work?

    Thanks,

    Scott

  • Hi AP,

    I think the problem is that the dropdownlist is within a Wizard template step -- and so you can't use the VB handles event syntax to wire-up an event on it.

    Instead, you should manually add a "onselectedchange" attribute to the dropdownlist control to point at the event handler in your code-behind.

    Hope this helps,

    Scott

  • Hi Wazzup,

    You can use the Membership.GetUser() method to return a MembershipUser object for the user you want to lookup. You can then use this to reset or change someone's email address.

    Hope this helps,

    Scott

  • Hi I am new to asp.net 2.0 I have some questions here, I would like to build a website that allows user to create a new account and login to the website, and one more thing I would like to do is allow user to save their own information in my website like Full name, Phone NO, Address and so on, and after user login, they are able to change their information and save it again. And base on this can I use built in asp.net 2.0 database to achieve these functions? or I need to create a new database? And one more thing that I would like to know is if I use asp.net 2.0 profile provider, could I achieve those function oso ? And the built in asp.net 2.0 user database is suit to which kind of website? Thanks! :(

  • Hi Scott, How can I add a checkbox rather than a textbox or dropdown list as in your example? I am trying the following: &nbsp; &nbsp;&lt;profile enabled="true"&gt; &nbsp; &nbsp; &nbsp;&lt;properties&gt; &nbsp; &nbsp; &nbsp; &nbsp;&lt;add name="Any" type="CheckBox"/&gt; etc. in web.config and in the .cs // Populate some Profile properties off of the create user wizard p.Any = (CheckBox)CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("Any").NamingContainer; The compile errors say I am missing an assembly reference to the type="Checkbox" so when I tried "Boolean" but the profile's value is System.Web.UI.WebControls.CheckBox. Can you help? Thank you.

  • Hi L. Pulsifer,

    What you'll want to store in the profile is not a checkbox -- but rather a boolean value that maps to the CheckBox's value.

    Hope this helps,

    Scott

  • I am trying to follow your example in VB and I get the below error. I will appreciate if you try to fix this for me. I am not able to save profile for user. System.NullReferenceException was unhandled by user code &nbsp;Message="Object reference not set to an instance of an object." Protected Sub CreateUserWizard1_CreatedUser(ByVal sender As Object, ByVal e As System.EventArgs) Handles CreateUserWizard1.CreatedUser &nbsp; &nbsp; &nbsp; &nbsp;Dim p As ProfileCommon &nbsp; &nbsp; &nbsp; &nbsp;p = ProfileCommon.Create(CreateUserWizard1.UserName, True) &nbsp; &nbsp; &nbsp; &nbsp;'If p Is Nothing Then &nbsp; &nbsp; &nbsp; &nbsp;p.SemaID = (CType(CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("txtsemaid"), TextBox)).Text &nbsp; &nbsp; &nbsp; &nbsp;p.Save() &nbsp; &nbsp; &nbsp; &nbsp;' Else &nbsp; &nbsp; &nbsp; &nbsp;Response.Write("Error") &nbsp; &nbsp; &nbsp; &nbsp;' End If &nbsp; &nbsp;End Sub

  • the article was really useful but is it possible to use the same idea without the wizard using something like this Public Sub CreateUser_Click(ByVal sender As Object, ByVal e As EventArgs) Handles CreateUser.Click &nbsp; &nbsp; &nbsp; &nbsp;Membership.CreateUser(UserName.Text, Password.Text, Email.Text) Dim p as Profile.Common=???????? &nbsp; &nbsp;p.Country = country.text &nbsp; &nbsp; &nbsp;p.Gender &nbsp;= gender.text &nbsp; &nbsp;p.Age &nbsp; &nbsp; = age.text &nbsp; &nbsp;End Sub if so what would the missing code be? many thanks martin

  • Hi Martin,

    Yep -- you can absolutely use the concepts without requiring the CreateUserWizard control.

    The missing line of code you are looking for looks like this:

    Profile = Profile.Create(userName.Text)

    Hope this helps,

    Scott

  • Hi Ashok,

    Can you send me email (scottgu@microsoft.com)? I can then point you at a utility that allows you to use strongly-typed profile properties with the VS 2005 Web Application Project.

    Hope this helps,

    Scott

  • Hi Scott,

    In my recent ASP.NET 2.0 appl, I need to verify that the supplied email address is valid or not. So, here's my situation:
    - In my area, I created property.
    - Suppose a new user has been created. I set the profile.isverified to false.
    OnCreatedUser event I'll send him an email (to the supplied email address) to verify their email address with a link in it to an ASPX page that'll do the verification, e.g: verify.aspx?u=aUserName
    - On page_load of verify.aspx, I want to change the property to true and set the to true, so he can start log in.

    How to do this? I'm using ASP.NET 2.0 (VB.NET) and MSSQL 2K for membership database.

    Thanks in advance,
    Andy

  • Hi Andy,

    When you create the new user using the Membership API, you can actually mark the account as not approved directly via the Membership API. What this means is that you don't need to use the Profile API for this.

    You'd then send them a dynamic random URL to click to activate the account. You could to this using the System.Net.Mail namespace -- which you can learn more about here: http://weblogs.asp.net/scottgu/archive/2006/01/03/434453.aspx

    One the page that they link back to from, you'd then write code like this to activate the account

    Dim userdetails as MembershipUser
    userdetails = Membership.GetUser(username)
    userdetails.IsAppoved = true
    Membership.UpdateUser(userdetails)

    Hope this helps,

    Scott

  • Hi Scott,

    How would one go about adding a 2nd password into
    the login? I would imagine that I'd have to write a custom membership class, and my own login control. But what would initiate the authentication process?

    Regards
    Firoz

  • Hi Firoz,

    There are a couple of ways you could do this. One would be to take the built-in ASP.NET Membership Provider and customize/extend it to support another column for a second password, and then just have the ValidateUser method check both passwords.

    If you use this approach then you don't need to re-implement any Login controls -- since they'll just call into your provider method (whose signature would stay the same).

    This website has tons of information on how to build providers, and also includes the source-code to the built-in ASP.NET ones: http://msdn.microsoft.com/asp.net/downloads/providers/

    Hope this helps,

    Scott

  • Great article! Exactly what I was looking for. One question if you don't mind Scott... can you explain a little bit about what happens to the database once you add the custom profile properties to the web.config file? Does it actually create new columns in the database to store this data? If so, at what point does it commit the db changes? If not, where do these new profiles properties get stored?

  • Hi Scott,
    Thanks for the above info. I discovered the &quot;convert to template&quot; option in the login control, and added my extra password field. I didn&#39;t know you could do this, hence I thought that I would have to write a new login control, etc.
    Thanks very much again
    Firoz

  • Hi SixSide,

    The default Profile provider uses an XML blob structure to store the data in a database. This avoids you having to explictly create columns in a table.

    If you want to map directly against columns in a table (or against a set of SPROCs), you can alternatively use the Profile Table Provider here: http://weblogs.asp.net/scottgu/archive/2006/01/10/435038.aspx

    Hope this helps,

    Scott

  • Scott,

    Great job!!! This article helped me a lot in my current project. However now I am facing a two new challenges:

    1. In addition to First and Last names, I need to add another field (Company_ID) as a property of the new user. Checking the database structure I found that it uses GUID fields instead of numeric ones (such as long integers), so I created the Company table using that type of field for primary key (Company_ID). Now I am trying to link that field to the Company dropdown box and it does not work.

    2. Is it possible to change the structure of the database to use numeric values for primary keys? Or do you recommend to change the primary keys in my tables to use GUID type instead? I do not want to mix both types but it is easier for me to work with auto-generated numeric values.

  • Hi Alvaro,

    If you want to store this information in custom database tables yourself, you might find this article particularly useful: http://aspnet.4guysfromrolla.com/articles/070506-1.aspx

    Hope this helps,

    Scott

  • hi ScottGu

    Can i ask is there a way to insert to the membership.mdf ?

  • Ok, different question... can you programatically log someone in without using the login control?

    It's for an admin page, and I want to see what that user sees...

  • Hi Iron,

    Yep -- you can definitely log people in manually. This page has a bunch of links on security that you might find useful: http://weblogs.asp.net/scottgu/archive/2006/02/24/ASP.NET-2.0-Membership_2C00_-Roles_2C00_-Forms-Authentication_2C00_-and-Security-Resources-.aspx

    This link then talks about how to programmatically login: http://msdn.microsoft.com/library/en-us/dnpag2/html/paght000014.asp

    Hope this helps,

    Scott

  • Great stuff Scott, any update on VB samples?

  • Based on your code above (gathering info from a DropDownList), I am having trouble inserting into the Profile table using a ListBox control with multiple items selected. Any code-snippets or insight is appreciated.

  • Hi 11HerbsAndSpirces,

    This more recent blog post (and the article I link to) should help with the VB version: http://weblogs.asp.net/scottgu/archive/2006/07/05/Tip_2F00_Trick_3A00_-Gathering-Custom-User-Registration-Information.aspx

    Hope this helps,

    Scott

  • I'm having a problem with:

    Dim p as ProfileCommon

    It is giving me an error of "Type ProfileCommon is not defined."

    I've added all the web.config Profile properties and such. It won't go away. Can you help me?

  • Hi Aaron,

    Where are you declaring this code? Is it within your page?

    Thanks,

    Scott

  • Hey Scott,

    I'm currently developing a system simular to partners.microsoft.com and Passport. The web app is for companies to communicate on latest info and updates. I'm building the registration currently and need to know if I could use Profiles or if this requires a more "direct" approach to the database. I want to store the "employee" along with the "company" without multiple copies of the "company". I know it may be confusing, but I must use this setup for a successful system. Thank you for the advice...

  • Hi Ray,

    I believe you could use Profiles to-do this. Alternatively, you could also store this registration data directly within a database. This article has information on how you could do this and links to some other great articles you might want to check out: http://weblogs.asp.net/scottgu/archive/2006/07/05/Tip_2F00_Trick_3A00_-Gathering-Custom-User-Registration-Information.aspx

    Hope this helps,

    Scott

  • Hi Scott,
    Great job as usual.
    I have a question regarding the userid Guid. Couldn't find any correct answer anywhere, so you are my last chance !
    I will have thousands of records in my database, and the userid will be in many tables and stored procedures. Regarding performance, can I keep this uniqueidentifier for all my stuff, or should I use an IDENTITY (and in that case associate the userid guid in a table to make the link between both).
    So Guid vs Int : what's your recommandation regarding performance?
    Thanks for your help.

  • Hi JCFromFrance,

    That is a good question, and to be honest with you I haven't ever profiled SQL to see if there is any substantial difference between using a GUID and an INT for a column key. I suspect a INT would be faster -- but don't really know how much for sure.

    Hope this helps,

    Scott

  • hi scott, your article is a very good , i'm developer asp.net(C#) 2.0 and i have a company i want help for find new way , get monye and new way for build our projects.
    i give many project from larg company but can't write Een one line code ... i know C# , asp.net.
    plz help me

  • One of the best articles i've read on the login controls yet. I am really stuck though. If i'm using a sql server and I want to add extra fields for the user, how do I make these update on the sql server? Is it done using the same way or not?

  • Hi Hayden,

    In general for adding additional fields that are user specific, I'd recommend using the "Profile" feature above. It is designed to allow you to store extra columns of information about your users.

    This article helps explain how you can map the Profile provider to a regular SQL table if you want to map these properties to an underlying SQL table or set of SPROCs: http://weblogs.asp.net/scottgu/archive/2006/01/10/435038.aspx

    Hope this helps,

    Scott

  • Hi Scott

    Great article. I have implemented something similar, based on the above, however I am stumped at the moment!! I want to redirect users after they login to the page appropriate to their role. So I set the destinationpage to a "redirect" page that contains logic in the page_Load to redirect the user something like for
    User.IsInRole("CLIENT")) Response.Redirect("candidate\default.aspx");

    I can't get it to work , any thoughts. i believe that my access rules and web.confg are correct but i can't figure out how to redirect users after login based on role. Any thoughts ?

    Again great articles , a credit to asp.net.

    Aidan

  • re my last post ..I think I have it working , its seems to do as i wanted . I'd appreciate any feed back any of you have...

    I created a page Rediret.aspx at root.
    i set this as the Destination_Page of the login control.
    I have two roles set up RoleX and RoleY these are configured with the appropriate deny /allow in web.config as below..


    code behind (redirect.aspx.cs)..
    protected void Page_Load(object sender, EventArgs e)
    {
    //SetAuthCookie(strUserName,true);
    if (User.IsInRole("RoleX"))
    Response.Redirect("RoleX_Folder/Default.aspx");
    else if (User.IsInRole("RoleY"))
    Response.Redirect("RoleY_Folder/Default.aspx");

    }

    web.config..








  • "We'll also be shipping another profile provider on the web that will allow you to bind the profile against an already defined database table as well. That way you'll also be able to integrate with existing data and perform even richer queries/updates on them."

    Has this been done yet and if so where can I get it?
    Thanks,
    Andre

  • Hi, I have a doubt, i've implemented this but what if i want people to update their profile? Thanks in advance and excellent work here.

  • Hi Scott, great article - you have a great way of explaining things clearly!
    Just a quick question though, I am having a problem with a dropdownlist added to the CreateUserStep - I can reference it in my codebehind file, but for some reason, it always returns the first value in the list as the selectedItem, not the actual selected item. Any ideas? Thanks in advance!

  • Hi Andre,

    Yep -- the SQL Profile Table Provider shipped back in January. You can learn more and download it here: http://weblogs.asp.net/scottgu/archive/2006/01/10/435038.aspx

    Hope this helps,

    Scott

  • Hi Max,

    That is odd -- do you have viewstate turned off for the page? I'm wondering if that is causing the value not to be persisted across the multiple steps.

    thanks,

    Scott

  • Hi Carlos,

    You could build a Profile page that allows users to customize their profile later. This tutorial shows one example of how to-do this: http://weblogs.asp.net/scottgu/archive/2006/07/22/Recipe_3A00_-Dynamic-Site-Layout-and-Style-Personalization-with-ASP.NET--.aspx

    Hope this helps,

    Scott

  • Scott - i've checked viewstate and it's on for the control - the page the control is in inherits from a master page - but the viewstate is on for that as well. Any ideas? The control works perfectly for textboxes etc but not for the dropdownlist.
    Any ideas? I'm stumped!
    Cheers,
    Max

  • hi

    i have everything working, i can create user and do all other sutff relating to that user using asp.net roles and membership and login controls. Now i want to collect some other information from user i.e. personal details. i have added a custom step after create user. But the problem is when user go throug the first step and click user button, the user is created in the database. and user can skip the second step, which is compulsory in my case.
    what i want is if user skip the second step by closing browser window or going to other page of site, the user which is created in first step gets deleted.is it possible?
    How can customize the "Create User" onclick event so that it just works as continue button and after second step when user clicks finish button, user is created. thanks in advance

    regards

  • Hi Scott,
    Just thought i'd drop you a line to say i've fixed my problem - schoolboy error i'm afraid - i was programmatically loading the dropdownlist and forgot to put an if (!Page.IsPostBack) on the page_load! Argh! Ah well, it works now - cheers anyway :P
    Max

  • hi

    i have everything working, i can create user and do all other sutff relating to that user using asp.net roles and membership and login controls. Now i want to collect some other information from user i.e. personal details. i have added a custom step after create user. But the problem is when user go throug the first step and click user button, the user is created in the database. and user can skip the second step, which is compulsory in my case.
    what i want is if user skip the second step by closing browser window or going to other page of site, the user which is created in first step gets deleted.is it possible?
    How can customize the "Create User" onclick event so that it just works as continue button and after second step when user clicks finish button, user is created. thanks in advance

    regards

  • Hi Max,

    Can you send me an email with a code example I could look at?

    Thx!

    Scott

  • Scott,
    Excellent article as per usual.

    I have an asp:login control that works perfectly (using SqlMembershipProvidor) in a normal aspx page.

    If I put the control in a contentplaceholder (in a content page) the "Log In" will not fire anything. I.e. clicking on the button, you see the button image alter but nothing happens.

    Can you point me in the right direction.

    Thanks and regards

    Simon

  • Hi Simon,

    That seems pretty odd. Can you double check to make sure there is a form element in the master page and there aren't any html errors? What you are describing sounds a little like it might be that.

    Do other form elements (normal textboxs and buttons) work on the page?

    thanks,

    Scott

  • Why can't I use Profile in WebApplicationProject?
    Error is that not found profile,but can use in the common VS2005 web Site.

  • Hi Death,

    You can use the Profile in a VS 2005 Web Application Project. However the Profile proxy class isn't automatically generated for you. Instead you should download and use this add-in to generate it: http://www.gotdotnet.com/workspaces/workspace.aspx?id=406eefba-2dd9-4d80-a48c-b4f135df4127

    Hope this helps,

    Scott

  • Hi Simon,

    That is pretty weird. If you want to send me a simple .zip file that repros the problem I can take a look for you.

    Thanks,

    Scott

  • Hi Scott,
    You can ignore the issue about the asp:login not firing as it has fixed itself. I was working on some non-security stuff, deployed it to the test server and then noticed that the login was working correctly. I tested it again and it works????

    I'm happy.

    Thanks for your time.

    Simon

  • When I run this code:

    ProfileCommon newProfile = (ProfileCommon)ProfileCommon.Create(NewUserName,true);

    I get an InvalidCastException. Unable to cast System.Web.Profile.DefaultProfile to type ProfileCommon. I've integrated the aspnet_Profile table into our SQL Server 2005 DB and made the necessary changes in the web.config.

    What I'm I doing wrong?

    Thanks

    Richard

  • Hi Richard,

    Are you using a Web Site Project or a Web Application Project?

    Thanks,

    Scott

  • Hi Scott Great article, We are creating an ASP.NET 2.0 application with Oracle database.
    We are planning to recreate the membership, roles and profiles (aspnetdb) tables, views and SP&#39;s in Oracle
    Before that I would like to know is there any other way other than recreating everything manually. I mean some tools or db script ready to download?

  • Hi Marty,

    You can definitly create your own "Provider" for the Profile API to call into your existing library object.

    This blog post will help show an example of how to-do this: http://weblogs.asp.net/scottgu/archive/2006/10/13/Tip_2F00_Trick_3A00_-Source_2F00_Documentation-for-Simple-ASP.NET-2.0-SQL-Providers-Published.aspx

    Hope this helps,

    Scott

  • hi, i want to create a login for my shopping cart assignment. my question is why is it that i cannot add additional step(collecting other user info such as address,mobile no) in the create wizard template AFTER the default createwizard step(username,password). I have created my own table,fields to store all the additional user info. Everything is working fine if i add steps BEFORE the default createwizard steps but not after. Any ways for me to overcome this problem?

    If i were to use Profile API, will it be difficult if i need to perform some cross table queries on my user data or even doing some simple edit/update function? Profile API seems rather complicated to use somehow.

    I am confused on which method to use. Pls Advise.

  • Hi San Jun,

    This article will probably help with what you are after: http://aspnet.4guysfromrolla.com/articles/070506-1.aspx

    Hope this helps,

    Scott

  • thanks for the article and that is exactly what i did for my project. my question is how can i make the default createwizard step as the first step and not the last step(like what the article did). it will not work when i just swop the steps order around. my objective is to collect username and password first before asking them for other information.

    thanks again for any futher assistance.

  • UPDATE: WOO HOO!!!

    I fixed it AND I'm an idiot! When retrieving the RETURN_VALUE from my stored procedure I was storing it in a local variable that I declared as an "int" as opposed to an Int32 like I should have b/c that was the type I declared ContactID to be in my Profile!!!

    :)

  • Hi, excellent article!

    Can I save a bitmap in profile? I couldn't assign it. After Profile.Save() there was alwas null in System.Drawing.Bitmap property.

  • Scott
    is there a way to create a page that will let me delete or modify users, create roles or delete roles?

    thanks
    Mark

  • Hi Mark,

    Here are two articles you might want to check out to learn how to create pages to manage roles:

    http://weblogs.asp.net/scottgu/archive/2006/07/23/Recipe_3A00_-Implementing-Role-Based-Security-with-ASP.NET-using-Windows-Authentication-and-SQL-Server.aspx

    and

    http://weblogs.asp.net/scottgu/archive/2006/07/18/Remote-Membership_2F00_Roles-Management-of-ASP.NET-2.0-Applications.aspx

    Hope this helps,

    Scott

  • Hi Petr,

    Good question -- I'm not actually sure. Any object saved in the profile needs to be serializable - it could be that BitMap picture objects aren't.

    Thanks,

    Scott

  • Hi John,

    There is an "IsApproved" property on the MembershipUser class that you can set to lock/unlock users from a system.

    You can retrieve this object like so:

    MembershipUser user = Membership.GetUser("scottgu");
    user.IsApproved = false;
    Membership.UpdateUser(user);

    Hope this helps,

    Scott

  • Hi Scott,

    This is regarding using Membership API to login a user.

    I have following code but it redirects page to Default.aspx and iwant membership API to redirect it to the page I choose. How could I change following code

    if ( Membership.ValidateUser( TextBox1.Text, TextBox2.Text ) )
    FormsAuthentication.RedirectFromLoginPage( TextBox1.Text, false );

    All the examples I have seen so far has a Login.aspx and a Default.aspx

    Thanks in advance

  • Hi Salil,

    There is an attribute you can set within the section of your section within the web.config file of your application.

    This allows you to configure the default redirect page of the application.

    Hope this helps,

    Scott

  • Hi Scott,
    I have a table users in my sql server 2005 database creamworks how can i link this table to asp.net profile.

    Thanks

  • Hi Paul,

    One suggestion would be to handle it within your Global.asax file's Application_Start event. I demonstrate a similar technique for doing this with roles in my blog post here: http://weblogs.asp.net/scottgu/pages/Recipe_3A00_-Implementing-Role_2D00_Based-Security-with-ASP.NET-2.0-using-Windows-Authentication-and-SQL-Server.aspx

    Hope this helps,

    Scott

  • Thanks Scott: This appears to be exactly what I was looking for.

  • Hey Scott: Did a modification of your Global.asax idea noted above. &nbsp;Rather than create the roles (and users) in the Global.asax file, I simply called a function createSec() from global.asax&#39;s Application_Start event, and did the additions there (in a *.vb file). This way, the stuff is compiled in the application and not visually available. Seems to work. Thanks again for getting me pointed in the right direct.
    Cheers!

  • Ok this profiling provider object is all so useful but if it was made for making profiles why is there no inbuilt capability to search it? Without going through every profile in the system and creating a collection?

  • Hi Scott, I was hoping you could point me in the right direction. I am trying to set up navigation (sitemap) for users that belong to a set of GROUPS and a set of CATALOGS (i.e. userA is in grp1,grp2 AND also in catX,catY,catZ). I would like to filter the menus based on both these criteria but am unable to see how using just the single set of defined ROLES i can define. So for a menu item i can define grp1 and catX and only users w/ both those securities can see it.

    I have looked at creating custom IDENTITY's and PRINCIPALS but am not sure how to combine all the concepts to arrive at a solution.

    Any help would be greatly appreciated. Thanks in advance,

    Gust..

  • Hi Scott,

    I read in your posts that you where considering doing something similar for VB.NET. I was would be greatful if you could point to the correct link if you have already posted it.

    Thanks

  • I dont get this one to work!...I use exactly the sam code as you, but I can for example not choose more than one role in the listbox (even if I have SelectionMode="Multiple" for the listbox....

    All the other things works fine....Usernamn, password are saved correctly in aspnet_membership and the profiles are saved in aspnet_profile....

    Its the role-part that not work for me...For the first can I only select one role..and for the second are nothing saved in aspnet_UsersInRoles...Which it should...Or should it?

    Maybe someone know what the problem can be?

  • Hi Marcus,

    What code are you using to retrieve the roles and update them in the Role Provider?

    Thanks,

    Scott

  • Hi Scott,

    I have Admins and Operators roles. I want to have the Operators accounts created only by the admins. This means that initial information for an operator will be provided by an admin and an email with the username and password will be sent to the operator. The operator will then change his/her password. But I also need to have the Security Question and Security Answer set for an operator. How do you think I should implement this?

    Thanks,
    Dako

  • Hi Scott,

    I'm planning to have a web site (I've already created the custom providers) and 2 kinds of users - admins and operators (2 roles). The admins are creating the accounts for all the users. This means that they are creating all the passwords (or these will be autogenerated) and the secret questions and answers. I want a user to be able to change his/her password and secret question/answer. Should I send an email with a link for activating the account and at that moment also ask for changing these? Also, if an user will forget the password and the secret answer, I want the admins to be able to reset them.
    What do you think is the best solution for this?

    Thanks,
    Dako.

  • Hi Dako,

    It probably makes sense to implement role-based security, and create two roles: operators and admins. You can then lock down the create-user page to only be accessible by admins. You can then build another page that is available to operators that allows them to change the password.

    If you use the CreateUserWizard control there is a property that you can set that will prevent the user being created from automatically being logged in (you'll want to set this so that when an admin creates the role they don't get logged out).

    Hope this helps,

    Scott

  • Hi Scott,

    Thanks a lot for your time. I still have some questions :)

    Is it ok to allow the operators to change also the secret question/answer in the same page they are changing the password? If so, can I somehow extend the ChangePassword control? Does it make any sense to do this?

    Also, what should I do if an operator forgets the password but also the secret answer? I'm using hashed passwords and I'm having EnablePasswordReset set to true and EnablePasswordRetrieval set to false. I guess the operator should be able to send an email and an admin should reset the values for the operator. How does it sound?

    Thanks & best regards,
    Dako.

  • Scott,

    I don't understand what's wrong with my code. The day I wrote it, it was working fine. Today when I'm trying to run it again, the line:

    Dim userprofile As ProfileCommon = CType(ProfileCommon.Create(CreateUserWizard1.UserName, True), ProfileCommon)

    gives me the following error:
    "Type 'ProfileCommon' is not defined."

    Please help!

  • Hi hrmalik,

    This might be caused by a configuration error in your web.config file. Can you open it and check to make sure everything there is right?

    Thanks,

    Scott

  • Hi Dako,

    I think you could allow the operators to change the secret question/answer if you wanted to. You can use the Membership API to control this.

    If someone forgets their password, then you can use the MembershipUser.ResetPassword() method to reset a new one for them.

    Hope this helps,

    Scott

  • Hi Scott,

    Thanks for the great article. I've implemented your example to a web application of mine, and I'd say has 85% operational functionality.

    I do have an issue, with regards to the Profile handler, what are the changes done to the database tables once I introduce these new profiles (which include the new fields to my registration page), apparently I did everything mentioned on your page, but for some strange reason, the page takes alot of time, and comes to an error message:

    "An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified) "

    I check the database, and the member is added, but minus the profile information.

    Which provider is the error message talking about?

  • amazingly good, I was expecting same thing from profile system

  • Hi Mohamed,

    I suspect you have an error with how you've registered your provider, and so it can't connect to the database.

    How did you register the connectionString and provider in your web.config file?

    Thanks,

    Scott

  • I don't get it.
    Even if we change the code, what about the stored procedures and the database fields ??

    can you explain ?

    I am trying to work on it but something is just not clicking to me :S

  • hope you are fine. i was just wondering how can i store the values in database using "add a Login, Roles and Profile system to an ASP.NET 2.0 app in only 24 lines of code". i tried this thing but its not saving in the database....although i created the fields myself.

    any suggestions ?

  • hey Scott,

    I created the pages according to what you said and added my own fields in the database. its not giving any error but its not entering the values in the database. it is adding the username and stuff....but not my fields which are












    which are in a system.web tag.

    and in the database i made fields for these...it did not work....then i deleted the fields...still not working...

    any suggestions ??

  • hi Scott
    Do i have to create a database with SQL 2000/2005 in order to use the Createuser wizard to build a membership website that someone can create their own account
    Tommy

  • We currently have our own customer/login tables in our database linked with CustomerID columns of both tables. Some of the requirements of the system are

    1) When I validate users, I need to pass more parameters than just username/password, for example customers are created for different clients, so I need to pass our ClientID with username/password together. We build one portal to support multiple clients.

    2) When a customer is validated, I need to get CustomerID instead of username from Context.User.Identity.

    By implementing MembershipProvider class, I don't think I can achieve any of requirement mentioned above.

    Any idea?

  • Hi Hardy,

    If you create a custom MembershipProvider you should be able to implement the above requirements. Note that you can also always call Membership.Provider.CustomMethod() to invoke custom methods on your provider implementation - so that would be another way to surface extra functionalit yif you want.

    Thanks,

    Scott

  • Hi Scott,

    How would you go about creating a user with additional user information in one step using the create user wizard and dropping the data in the existing table(s) with the other data? I thought I could just override the membership.createuser method and specify the additional parameters (which seemed logical), but this apparently cannot be done. Thanks!

  • Hi Derek,

    This blog post has more information that I think will help you: http://weblogs.asp.net/scottgu/archive/2006/07/05/Tip_2F00_Trick_3A00_-Gathering-Custom-User-Registration-Information.aspx

    This article in particular talks about how to store the information from CreateUser directly into a database: http://aspnet.4guysfromrolla.com/articles/070506-1.aspx

    Hope this helps,

    Scott

  • hi scott

    when will you release the vb.net version?i have already create the database what if i tried to implement your codes, will the user registered will be affected? Thanx

  • hi scott,
    i got the code up an running and it worked fine, but If i were to integrate it with my local database, should i create a new table for country, age and gender? or they were automatically created ......

  • hello there
    i've been following your tutorial on custom membership.i'm adding a new field in the wizard control. i'm getting Object reference not set to an instance of an object error. Can i email you the details of what i wrote or i can just spill it here...... been doing this for a very long time...

  • Hi Saigei,

    Sure - feel free to email me what you built and I can try and help.

    Thanks,

    Scott

  • Hi Scott,

    First off, thanks for the great posts. You definitely know what your talking about.

    Second, I have a problem that, at first, I thought the profile feature could solve but now I'm not so sure. Your advice would be greatly appreciated.

    I'm using the profile to store some extra user data (like a companyId, fullname). I want to be able to, from admin pages or whatever, filter all the memberships by these extra pieces of data. For instance, if I wanted an admin to only be able to manage the memberships for companyA from code I should easily be able to get a list of the members who's profile has companyA for thier companyID.

    From what it seems if I wanted to build a wrapper to give me a list of usernames who's profile fit the criteria I'd have to hit the db for each user by building their profileCommon via profil.getProfile. Doesn't seem like a good idea. The profileManager seems like it only helps me report on profile stats and do maintenance, not view all the user's profile data. Is there a way to do this with the profile API?

    I'd rather not use the ProfileTableProvider to let me build these queries because it would tie me to a particular datastore and kinda defeats the whole datastore neutral idea.

    Am I missing something? Am I using the profileAPI incorrectly? Any advice on a direction I should take?

    Thanks in advance,
    Dane

  • hi i'm wondering how do i get these codes embeded in my web.config. all these while i had to do them manually. and what does the type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> do?







  • I'd like to add a new user profile as an Employer might add an Employee....assign roles, email address...etc

    How do I reference profile data to accomplish this ?

    Thanks, Daren

  • I would like to know how to use visio as a dynamic web page in visio.

  • Hello,

    I have checked it for Oracle. But the cod eis not working, Could you please tell, what I have to do to connect it with Oracle?

    Thanks
    Ceema

Comments have been disabled for this content.