Membership APIでユーザー名を変更することは可能ですか?
質問
ASP.NETでデフォルトのsqlメンバーシッププロバイダーを使用しています。ユーザーのユーザー名を変更するページを提供したいと思います。カスタムプロバイダーでこれを実行できると確信していますが、これはデフォルトプロバイダーで実行できますか?
私の質問の2番目の部分は次のとおりです。 アカウントの作成後にユーザーにユーザー名の変更を許可する必要がありますか?
解決
デフォルトのSQLメンバーシッププロバイダーがユーザー名の変更を許可していないのは事実です。ただし、サイトで有効な引数を使用して許可している場合、ユーザーがユーザー名を変更できないようにする本質的な理由はありません。 SQLデータベースのテーブルはいずれもキーとしてユーザー名を持ちません。すべてがユーザーのIDに基づいているため、実装の観点からはかなり簡単です。
他のヒント
SqlMembershipProvider
を使用する場合、拡張できます-また、この質問。
Roadkill はwikiエンジンであり、コーディングスタイルの説明ではありません。
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;
}
}
}
}
}
Scott Mitchellには、この状況を処理する方法を説明した素晴らしい記事があります: http:// www.4guysfromrolla.com/articles/070109-1.aspx
彼の記事からの重要な引用:
残念ながら、理想主義とプラグマティズムが交差することはめったにありません。ユーザーにユーザー名の変更を許可する場合など、場合によっては、基になるデータストアと直接連携する以外に選択肢はありません。
また、ユーザー名/メールを変更した後にユーザーを再認証する方法も示しています。
Membership APIを使用してこれを行う場合、正しい方法は次のようになります。
http://omaralzabir.com/how_to_change_user_name_in_asp_net_2_0_membership_provider/
基本的に、次のことを行う必要があります(完全を期すために、上記のリンクからコピーしました):
- 新しいメールアドレスを使用して新しいユーザーを作成
- 古いアカウントのパスワードを取得し、新しいアカウントに設定します。メンバーシッププロバイダーから古いパスワードを取得できない場合は、ユーザーに確認してください。
- 新しいユーザーアカウントの新しいプロファイルを作成
- すべてのプロパティを古いプロファイルから新しいプロファイルオブジェクトにコピーします。
- 古いアカウントからユーザーをログアウトします
- 新しいアカウントに自動サインインして、ユーザーが信じられないような事態が発生したことに気付かないようにします。
Membershiop APIではユーザー名を直接変更できないため、データベースの aspnet_Membership
テーブルに直接アクセスできます。
これは、Enterprise Libraries DABとその他のいくつかの小さな変更を組み込んだバージョンです。また、ブール値を返すことには意味がありません。ブール値は成功するか、例外をスローするためです。
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);
}
}
いいえ、MembershipUserクラスではUsernameプロパティを変更できないため、変更できません。
実際には、ユーザー名の変更を許可しないでください。どうにかして許可すると、その目的と性質が失われます。