我正在使用ASP.NET的默认SQL membership提供程序,并且我想提供一个页面来更改用户的用户名。我相信我可以通过自定义提供程序来实现这一点,但是默认提供程序能否做到呢?
我的第二个问题是: 我是否应该允许用户在创建账户后更改他们的用户名?
我正在使用ASP.NET的默认SQL membership提供程序,并且我想提供一个页面来更改用户的用户名。我相信我可以通过自定义提供程序来实现这一点,但是默认提供程序能否做到呢?
我的第二个问题是: 我是否应该允许用户在创建账户后更改他们的用户名?
确实,SQL Membership Provider 默认设置不允许更改用户名。但是,如果你在网站上有一个有效的理由允许用户更改他们的用户名,就没有本质的理由阻止它。 SQL 数据库中的所有表都没有用户名作为关键字,一切都基于用户 ID,从实现的角度来看,这将非常容易。
SqlMembershipProvider
,您可以对其进行扩展-这也与此问题有关。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;
}
}
}
}
}
RoadkillMembershipProvider
,并首先检查它是否属于该类型。 - Chris SScott Mitchell在这篇文章中详细介绍了如何处理这种情况:https://web.archive.org/web/20210927191559/http://www.4guysfromrolla.com/articles/070109-1.aspx
他的文章中有一个重要的引用:
不幸的是,理想主义和实用主义很少交汇。在某些情况下——比如允许用户更改用户名时——我们别无选择,只能直接与底层数据存储进行交互。
他还展示了如何在更改用户名或电子邮件后重新验证用户身份。
这里有一个版本,它包含了企业库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);
}
}
由于Membership API不允许直接修改用户名,因此您可以直接访问数据库中的aspnet_Membership
表。
MembershipUser类不允许修改Username属性,因此您无法这样做。
实际上,您不应该允许更改用户名。如果您以某种方式允许更改,则会失去其目的和性质。