我试图在没有实体框架的情况下实现aspnetcore身份并使用直接连接到SQL Server,到目前为止我创建了identityuser,userstore和usertable。我正在尝试使用默认的Register View注册一个新用户,并使用默认的Accounts控制器的Register方法调用_usermanager.CreateAsync,它总是抛出错误用户名是什么 用户名''是无效的,只能包含字母或数字它表示用户名'' 它没有说我输入的用户名但是显示'&#39 ;是吗?
在Startup.cs中配置服务如下所示
public void ConfigureServices(IServiceCollection services)
{
var roleStore = new RoleStore();
var userPrincipalFactory = new ExampleUserPrincipalFactory();
services.AddSingleton<IUserStore<IdentityUser>, UserStore<IdentityUser>>();
services.AddSingleton<IRoleStore<IdentityRole>>(roleStore);
services.AddSingleton<IUserClaimsPrincipalFactory<IdentityUser>>(userPrincipalFactory);
services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@";
}).AddDefaultTokenProviders();
services.AddMvc();
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
}
我使用过AllowedUsernamesCharacters,但没有区别。我很少有类似消息的其他旧例子建议在AccountsController构造函数中定义验证器,但是使用最新的aspnetcore,UserManager不再具有UserValidator属性
UserManager.UserValidator = new UserValidator<ApplicationUser>(UserManager) { AllowOnlyAlphanumericUserNames = false };
我怀疑我的IdentityUser的自定义实现,Usertore可能有一些错误,所以我会在这里给你这些文件
IdentityUser
public class IdentityUser
{
public IdentityUser()
{
Id = Guid.NewGuid().ToString();
}
public IdentityUser(string userName)
: this()
{
UserName = userName;
}
public string Id { get; set; }
public string UserName { get; set; }
public virtual string Email { get; set; }
public virtual bool EmailConfirmed { get; set; }
public virtual string PasswordHash { get; set; }
public virtual string SecurityStamp { get; set; }
public virtual string PhoneNumber { get; set; }
public virtual bool PhoneNumberConfirmed { get; set; }
public virtual bool TwoFactorEnabled { get; set; }
public virtual DateTime? LockoutEndDateUtc { get; set; }
public virtual bool LockoutEnabled { get; set; }
public virtual int AccessFailedCount { get; set; }
}
UserStore
public class UserStore<TUser> : IUserStore<TUser>,
IUserPasswordStore<TUser>,
IUserLoginStore<TUser>,
IUserPhoneNumberStore<TUser>,
IUserTwoFactorStore<TUser>
where TUser : IdentityUser
{
// Workaround create a new userTable instance when ever it is null
private UserTable<TUser> userTable
{
get
{
return new UserTable<TUser>(Database);
}
set
{
}
}
// Workaround create a new Database instance when ever it is null
public MsSqlDatabase Database
{
get
{
return new MsSqlDatabase();
}
private set
{
}
}
public IQueryable<TUser> Users
{
get
{
throw new NotImplementedException();
}
}
public UserStore()
{
new UserStore<TUser>(new MsSqlDatabase());
}
public UserStore(MsSqlDatabase database)
{
Database = database;
userTable = new UserTable<TUser>(database);
//roleTable = new RoleTable(database);
//userRolesTable = new UserRolesTable(database);
//userClaimsTable = new UserClaimsTable(database);
//userLoginsTable = new UserLoginsTable(database);
}
public Task<IdentityResult> CreateAsync(TUser user, CancellationToken cancellationToken)
{
if (user == null)
{
throw new ArgumentNullException("user");
}
userTable.Insert(user);
var a = IdentityResult.Success;
return new Task<IdentityResult>(() => a);
}
public async Task<string> GetUserIdAsync(TUser user, CancellationToken cancellationToken)
{
List<TUser> result = userTable.GetUserById(user.Id) as List<TUser>;
if (result != null && result.Count == 1)
{
return result[0].Id;
}
return null;
}
public async Task<string> GetUserNameAsync(TUser user, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(user.UserName))
{
throw new ArgumentException("Null or empty argument: userName");
}
List<TUser> result = userTable.GetUserByName(user.UserName) as List<TUser>;
// Should I throw if > 1 user?
if (result != null && result.Count == 1)
{
return result[0].UserName;
}
return null;
}
Task<TUser> IUserStore<TUser>.FindByNameAsync(string userName, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(userName))
{
throw new ArgumentException("Null or empty argument: userName");
}
List<TUser> result = userTable.GetUserByName(userName) as List<TUser>;
// Should I throw if > 1 user?
if (result != null && result.Count == 1)
{
return Task.FromResult<TUser>(result[0]);
}
return Task.FromResult<TUser>(null);
}
public Task SetPasswordHashAsync(TUser user, string passwordHash, CancellationToken cancellationToken)
{
user.PasswordHash = passwordHash;
return Task.FromResult<Object>(null);
}
public void Dispose()
{
if (Database != null)
{
Database.Dispose();
Database = null;
}
}
public Task AddLoginAsync(TUser user, UserLoginInfo login, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<IdentityResult> DeleteAsync(TUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<IList<UserLoginInfo>> GetLoginsAsync(TUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<string> GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<string> GetPasswordHashAsync(TUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<string> GetPhoneNumberAsync(TUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<bool> GetPhoneNumberConfirmedAsync(TUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<bool> GetTwoFactorEnabledAsync(TUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<bool> HasPasswordAsync(TUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task RemoveLoginAsync(TUser user, string loginProvider, string providerKey, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task SetNormalizedUserNameAsync(TUser user, string normalizedName, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task SetPhoneNumberAsync(TUser user, string phoneNumber, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task SetPhoneNumberConfirmedAsync(TUser user, bool confirmed, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task SetTwoFactorEnabledAsync(TUser user, bool enabled, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task SetUserNameAsync(TUser user, string userName, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<IdentityResult> UpdateAsync(TUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
Task<TUser> IUserStore<TUser>.FindByIdAsync(string userId, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
Task<TUser> IUserLoginStore<TUser>.FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
}
**UserTable**
public class UserTable<TUser> where TUser:IdentityUser
{
private MsSqlDatabase _database;
public UserTable(MsSqlDatabase database)
{
_database = database;
}
public string GetUserName(string userId)
{
string commandText = "Select Name from Users where Id = @id";
Dictionary<string, object> parameters = new Dictionary<string, object>() { { "@id", userId } };
return _database.GetStrValue(commandText, parameters);
}
public string GetUserId(string userName)
{
string commandText = "Select Id from Users where UserName = @name";
Dictionary<string, object> parameters = new Dictionary<string, object>() { { "@name", userName } };
return _database.GetStrValue(commandText, parameters);
}
public TUser GetUserById(string userId)
{
TUser user = null;
string commandText = "Select * from Users where Id = @id";
Dictionary<string, object> parameters = new Dictionary<string, object>() { { "@id", userId } };
var rows = _database.Query(commandText, parameters);
if (rows != null && rows.Count == 1)
{
var row = rows[0];
user = (TUser)Activator.CreateInstance(typeof(TUser));
user.Id = row["Id"];
user.UserName = row["UserName"];
user.PasswordHash = string.IsNullOrEmpty(row["PasswordHash"]) ? null : row["PasswordHash"];
user.SecurityStamp = string.IsNullOrEmpty(row["SecurityStamp"]) ? null : row["SecurityStamp"];
user.Email = string.IsNullOrEmpty(row["Email"]) ? null : row["Email"];
user.EmailConfirmed = row["EmailConfirmed"] == "1" ? true : false;
user.PhoneNumber = string.IsNullOrEmpty(row["PhoneNumber"]) ? null : row["PhoneNumber"];
user.PhoneNumberConfirmed = row["PhoneNumberConfirmed"] == "1" ? true : false;
user.LockoutEnabled = row["LockoutEnabled"] == "1" ? true : false;
user.LockoutEndDateUtc = string.IsNullOrEmpty(row["LockoutEndDateUtc"]) ? DateTime.Now : DateTime.Parse(row["LockoutEndDateUtc"]);
user.AccessFailedCount = string.IsNullOrEmpty(row["AccessFailedCount"]) ? 0 : int.Parse(row["AccessFailedCount"]);
}
return user;
}
public List<TUser> GetUserByName(string userName)
{
List<TUser> users = new List<TUser>();
string commandText = "Select * from Users where UserName = @name";
Dictionary<string, object> parameters = new Dictionary<string, object>() { { "@name", userName } };
var rows = _database.Query(commandText, parameters);
foreach (var row in rows)
{
TUser user = (TUser)Activator.CreateInstance(typeof(TUser));
user.Id = row["Id"];
user.UserName = row["UserName"];
user.PasswordHash = string.IsNullOrEmpty(row["PasswordHash"]) ? null : row["PasswordHash"];
user.SecurityStamp = string.IsNullOrEmpty(row["SecurityStamp"]) ? null : row["SecurityStamp"];
user.Email = string.IsNullOrEmpty(row["Email"]) ? null : row["Email"];
user.EmailConfirmed = row["EmailConfirmed"] == "1" ? true : false;
user.PhoneNumber = string.IsNullOrEmpty(row["PhoneNumber"]) ? null : row["PhoneNumber"];
user.PhoneNumberConfirmed = row["PhoneNumberConfirmed"] == "1" ? true : false;
user.LockoutEnabled = row["LockoutEnabled"] == "1" ? true : false;
user.TwoFactorEnabled = row["TwoFactorEnabled"] == "1" ? true : false;
user.LockoutEndDateUtc = string.IsNullOrEmpty(row["LockoutEndDateUtc"]) ? DateTime.Now : DateTime.Parse(row["LockoutEndDateUtc"]);
user.AccessFailedCount = string.IsNullOrEmpty(row["AccessFailedCount"]) ? 0 : int.Parse(row["AccessFailedCount"]);
users.Add(user);
}
return users;
}
public List<TUser> GetUserByEmail(string email)
{
return null;
}
public string GetPasswordHash(string userId)
{
string commandText = "Select PasswordHash from Users where Id = @id";
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("@id", userId);
var passHash = _database.GetStrValue(commandText, parameters);
if (string.IsNullOrEmpty(passHash))
{
return null;
}
return passHash;
}
public int SetPasswordHash(string userId, string passwordHash)
{
string commandText = "Update Users set PasswordHash = @pwdHash where Id = @id";
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("@pwdHash", passwordHash);
parameters.Add("@id", userId);
return _database.Execute(commandText, parameters);
}
public string GetSecurityStamp(string userId)
{
string commandText = "Select SecurityStamp from Users where Id = @id";
Dictionary<string, object> parameters = new Dictionary<string, object>() { { "@id", userId } };
var result = _database.GetStrValue(commandText, parameters);
return result;
}
public int Insert(TUser user)
{
string commandText = @"Insert into Users (UserName, Id, PasswordHash, SecurityStamp,Email,EmailConfirmed,PhoneNumber,PhoneNumberConfirmed, AccessFailedCount,LockoutEnabled,LockoutEndDateUtc,TwoFactorEnabled)
values (@name, @id, @pwdHash, @SecStamp,@email,@emailconfirmed,@phonenumber,@phonenumberconfirmed,@accesscount,@lockoutenabled,@lockoutenddate,@twofactorenabled)";
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("@name", user.UserName);
parameters.Add("@id", user.Id);
parameters.Add("@pwdHash", user.PasswordHash);
parameters.Add("@SecStamp", user.SecurityStamp);
parameters.Add("@email", user.Email);
parameters.Add("@emailconfirmed", user.EmailConfirmed);
parameters.Add("@phonenumber", user.PhoneNumber);
parameters.Add("@phonenumberconfirmed", user.PhoneNumberConfirmed);
parameters.Add("@accesscount", user.AccessFailedCount);
parameters.Add("@lockoutenabled", user.LockoutEnabled);
parameters.Add("@lockoutenddate", user.LockoutEndDateUtc);
parameters.Add("@twofactorenabled", user.TwoFactorEnabled);
return _database.Execute(commandText, parameters);
}
private int Delete(string userId)
{
string commandText = "Delete from Users where Id = @userId";
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("@userId", userId);
return _database.Execute(commandText, parameters);
}
public int Delete(TUser user)
{
return Delete(user.Id);
}
public int Update(TUser user)
{
string commandText = @"Update Users set UserName = @userName, PasswordHash = @pswHash, SecurityStamp = @secStamp,
Email=@email, EmailConfirmed=@emailconfirmed, PhoneNumber=@phonenumber, PhoneNumberConfirmed=@phonenumberconfirmed,
AccessFailedCount=@accesscount, LockoutEnabled=@lockoutenabled, LockoutEndDateUtc=@lockoutenddate, TwoFactorEnabled=@twofactorenabled
WHERE Id = @userId";
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("@userName", user.UserName);
parameters.Add("@pswHash", user.PasswordHash);
parameters.Add("@secStamp", user.SecurityStamp);
parameters.Add("@userId", user.Id);
parameters.Add("@email", user.Email);
parameters.Add("@emailconfirmed", user.EmailConfirmed);
parameters.Add("@phonenumber", user.PhoneNumber);
parameters.Add("@phonenumberconfirmed", user.PhoneNumberConfirmed);
parameters.Add("@accesscount", user.AccessFailedCount);
parameters.Add("@lockoutenabled", user.LockoutEnabled);
parameters.Add("@lockoutenddate", user.LockoutEndDateUtc);
parameters.Add("@twofactorenabled", user.TwoFactorEnabled);
return _database.Execute(commandText, parameters);
}
}
MySqlDatabase
public class MsSqlDatabase : IDisposable
{
private SqlConnection _connection;
public MsSqlDatabase()
: this("DefaultConnection")
{
}
public MsSqlDatabase(string connectionStringName)
{
string connectionString = "Server=(localdb)\\mssqllocaldb;Database=SampleIdentity;Trusted_Connection=True;MultipleActiveResultSets=true";
_connection = new SqlConnection(connectionString);
}
public int Execute(string commandText, Dictionary<string, object> parameters)
{
int result = 0;
if (String.IsNullOrEmpty(commandText))
{
throw new ArgumentException("Command text cannot be null or empty.");
}
try
{
EnsureConnectionOpen();
var command = CreateCommand(commandText, parameters);
result = command.ExecuteNonQuery();
}
finally
{
_connection.Close();
}
return result;
}
public object QueryValue(string commandText, Dictionary<string, object> parameters)
{
object result = null;
if (String.IsNullOrEmpty(commandText))
{
throw new ArgumentException("Command text cannot be null or empty.");
}
try
{
EnsureConnectionOpen();
var command = CreateCommand(commandText, parameters);
result = command.ExecuteScalar();
}
finally
{
EnsureConnectionClosed();
}
return result;
}
public List<Dictionary<string, string>> Query(string commandText, Dictionary<string, object> parameters)
{
List<Dictionary<string, string>> rows = null;
if (String.IsNullOrEmpty(commandText))
{
throw new ArgumentException("Command text cannot be null or empty.");
}
try
{
EnsureConnectionOpen();
var command = CreateCommand(commandText, parameters);
using (DbDataReader reader = command.ExecuteReader())
{
rows = new List<Dictionary<string, string>>();
while (reader.Read())
{
var row = new Dictionary<string, string>();
for (var i = 0; i < reader.FieldCount; i++)
{
var columnName = reader.GetName(i);
var columnValue = reader.IsDBNull(i) ? null : reader.GetString(i);
row.Add(columnName, columnValue);
}
rows.Add(row);
}
}
}
finally
{
EnsureConnectionClosed();
}
return rows;
}
private void EnsureConnectionOpen()
{
var retries = 3;
if (_connection.State == ConnectionState.Open)
{
return;
}
else
{
while (retries >= 0 && _connection.State != ConnectionState.Open)
{
_connection.Open();
retries--;
Task.Delay(30).Wait();
}
}
}
public void EnsureConnectionClosed()
{
if (_connection.State == ConnectionState.Open)
{
_connection.Close();
}
}
private DbCommand CreateCommand(string commandText, Dictionary<string, object> parameters)
{
DbCommand command = _connection.CreateCommand();
command.CommandText = commandText;
AddParameters(command, parameters);
return command;
}
private static void AddParameters(DbCommand command, Dictionary<string, object> parameters)
{
if (parameters == null)
{
return;
}
foreach (var param in parameters)
{
var parameter = command.CreateParameter();
parameter.ParameterName = param.Key;
parameter.Value = param.Value ?? DBNull.Value;
command.Parameters.Add(parameter);
}
}
public string GetStrValue(string commandText, Dictionary<string, object> parameters)
{
string value = QueryValue(commandText, parameters) as string;
return value;
}
public void Dispose()
{
if (_connection != null)
{
_connection.Dispose();
_connection = null;
}
}
}
ExampleUserPrincipalFactory
public class ExampleUserPrincipalFactory:IUserClaimsPrincipalFactory<IdentityUser>
{
public Task<ClaimsPrincipal> CreateAsync(IdentityUser user)
{
ClaimsIdentity identity = new ClaimsIdentity("Microsoft.AspNet.Identity.Application");
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
identity.AddClaim(new Claim(ClaimTypes.Name, user.UserName));
identity.AddClaim(new Claim(ClaimTypes.Email, user.Email));
ClaimsPrincipal principal = new ClaimsPrincipal(identity);
return Task.FromResult(principal);
}
}
如果您想查看其他课程定义,请告知我们。
答案 0 :(得分:0)
我的错误,UserStore.GetUserNameAsync应从(参数)用户对象获取用户名,但我试图从数据库中获取它,并且在该实例中它变为空,因此用户名始终为空并且验证失败