Is it possible to change the username with the Membership API
Asked Answered
A

7

32

I am using the default sql membership provider with ASP.NET and I would like to provide a page to change the user's username. I believe I am sure I could do this with a custom provider, but can this be done with the default provider?

Second part of my question is: Should I allow users to change their username after the account is created?

Ainslee answered 16/6, 2009 at 13:30 Comment(0)
M
24

It's true that the default SQL Membership Provider does not allow username changes. However, there's no intrinsic reason to prevent users from changing their usernames if you have a valid argument, on your site, to allow it. None of the tables in the SQL database have the username as a key, everything is based on the user's ID, so from an implementation perspective it would be fairly easy.

Manzo answered 16/6, 2009 at 14:3 Comment(3)
Though the db tables are based off a separate UserID key, the SPs that the .NET Membership provider runs are based off the user name. I haven't looked too closely into the source, but this seems to indicate that if you change a user's username, subsequent membership operations might fail (trying to use the old username).Pomcroy
Are Toby's concerns not an issue? It seems like "maybe some SPs might fail" is a pretty serious reason NOT to accept the answer or use it until it's validated. Any thoughts?Shipentine
If your code is still passing stale usernames into the provider after an update, then Toby is right, you will obviously have issues. Otherwise, there are no adverse effects.Manzo
C
12

If you use SqlMembershipProvider, you can extend it - it also relates to this question.
Roadkill is a wiki engine not a description of my coding style.

using System;
using System.Web.Security;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
using System.Web.Configuration;

namespace Roadkill.Core
{
    public class RoadkillMembershipProvider : SqlMembershipProvider
    {
        private string _connectionString;

        protected string ConnectionString
        {
            get
            {
                if (string.IsNullOrWhiteSpace(_connectionString))
                {
                    Configuration config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
                    MembershipSection section = config.SectionGroups["system.web"].Sections["membership"] as MembershipSection;
                    string defaultProvider = section.DefaultProvider;
                    string connstringName = section.Providers[defaultProvider].ElementInformation.Properties["connectionStringName"].Value.ToString();
                    _connectionString = config.ConnectionStrings.ConnectionStrings[connstringName].ConnectionString;
                }

                return _connectionString;
            }
        }

        public bool ChangeUsername(string oldUsername, string newUsername)
        {
            if (string.IsNullOrWhiteSpace(oldUsername))
                throw new ArgumentNullException("oldUsername cannot be null or empty");

            if (string.IsNullOrWhiteSpace(newUsername))
                throw new ArgumentNullException("newUsername cannot be null or empty");

            if (oldUsername == newUsername)
                return true;

            using (SqlConnection connection = new SqlConnection(ConnectionString))
            {
                connection.Open();

                using (SqlCommand command = connection.CreateCommand())
                {
                    command.CommandText = "UPDATE aspnet_Users SET UserName=@NewUsername,LoweredUserName=@LoweredNewUsername WHERE UserName=@OldUsername";

                    SqlParameter parameter = new SqlParameter("@OldUsername", SqlDbType.VarChar);
                    parameter.Value = oldUsername;
                    command.Parameters.Add(parameter);

                    parameter = new SqlParameter("@NewUsername", SqlDbType.VarChar);
                    parameter.Value = newUsername;
                    command.Parameters.Add(parameter);

                    parameter = new SqlParameter("@LoweredNewUsername", SqlDbType.VarChar);
                    parameter.Value = newUsername.ToLower();
                    command.Parameters.Add(parameter);

                    return command.ExecuteNonQuery() > 0;
                }
            }
        }
    }
}
Cedrickceevah answered 27/2, 2011 at 11:35 Comment(3)
@russau yep, I put that in the data annotations on the domain object. Either place is good thoughCedrickceevah
How do you call that method? I guess the membership api is what it is, so where I'm getting at is that the method could just as well (or better) have lived in a class that didn't inherit SqlMembershipProvider.Subplot
@Carl you need to cast your default provider to a RoadkillMembershipProvider checking it is of that type firstCedrickceevah
M
4

Scott Mitchell has a great article describing how to handle this situation here: https://web.archive.org/web/20210927191559/http://www.4guysfromrolla.com/articles/070109-1.aspx

Important quote from his article:

Unfortunately, idealism and pragmatism only rarely intersect. In some cases - such as allowing a user to change their username - we have no choice but to work directly with the underlying data store.

He also shows how to re-authenticate the user after changing their username/email.

Mic answered 28/8, 2012 at 5:17 Comment(0)
F
2

If you want to do that with the Membership API, it seems the right way would be like this:

http://omaralzabir.com/how_to_change_user_name_in_asp_net_2_0_membership_provider/

Basically, you have to do the following (I copied from the above link, for sake of completeness):

  1. Create a new user using the new email address
  2. Get the password of the old account and set it to the new account. If you can’t get the old password via Membership provider, then ask user.
  3. Create a new profile for the new user account
  4. Copy all the properties from the old profile to the new profile object.
  5. Log out user from old account
  6. Auto sign in to the new account so that user does not notice what an incredible thing just happened.
Finegan answered 1/11, 2010 at 16:29 Comment(1)
I would advice against doing it this way though: If you have other stuff tied to the UserID, you're risking losing a users content (especially as your system evolves and new things rely on the userID).Afterlife
I
0

Since Membershiop API does not allow username modification directly, you can access directly the aspnet_Membership table in your database.

Ikon answered 29/12, 2011 at 9:20 Comment(1)
I strongly advise against this approach. If you change the username directly on the AspNetUsers table that user will no longer be able to loginThanet
F
0

Here's a version that incorporates the Enterprise Libraries DAB and a couple other minor changes. Also, I don't see a point in returning a Boolean, since it's either going succeed or throw an exception.

        public static void ChangeUsername(string oldUsername, string newUsername)
    {
        if (string.IsNullOrWhiteSpace(oldUsername))
        {
            throw new ArgumentNullException("oldUsername cannot be null or empty");
        }

        if (string.IsNullOrWhiteSpace(newUsername))
        {
            throw new ArgumentNullException("newUsername cannot be null or empty");
        }

        if (oldUsername.Equals(newUsername))
        {
            return;
        }

        Database db = DatabaseFactory.CreateDatabase();
        using (DbCommand cmd = db.GetSqlStringCommand("UPDATE dbo.aspnet_Users SET UserName=@NewUsername, LoweredUserName=@LoweredNewUsername WHERE UserName=@OldUsername"))
        {
            db.AddInParameter(cmd, "@OldUsername", DbType.String, oldUsername);
            db.AddInParameter(cmd, "@NewUsername", DbType.String, newUsername);
            db.AddInParameter(cmd, "@LoweredNewUsername", DbType.String, newUsername.ToLower());

            db.ExecuteNonQuery(cmd);                
        }
    }
Florist answered 17/2, 2014 at 16:42 Comment(0)
I
-3

No, the MembershipUser class does not allow to modify the Username property so you cannot do it.

Practically you should not allow the username to change. If you allow to do so somehow then it will lose its purpose and nature.

Immovable answered 16/6, 2009 at 13:41 Comment(3)
I ended up writing my own provider. then I added this ability.Ainslee
it does not lose its purpose or nature at all. lets say you create [email protected] for an account. oops you mispelled geek! now you're totally screwed. customers will do this ALL the time. if you're using email as login you have a problemBeaubeauchamp
Why wouldn't you allow someone to change their username? It's not used to uniquely identify users within the Membership storage, as has been said in the comments above. What if your customer makes a typo in his name and wants to change it.Stephan

© 2022 - 2024 — McMap. All rights reserved.