我正在使用新的 ASP.NET 身份(RTM),我想知道如何继续将注册和登录从用户名更改为电子邮件。
这个想法是,我希望我的用户使用他们的电子邮件和密码进行注册(电子邮件也可以使用外部登录获取),并在顶部设置显示名称/用户名。
我查看了IdentityUser,我可以看到用户名在那里,但是因为它包含在无法更改 ASP.Net 身份中。
我知道我可以使用"用户名"作为电子邮件,带有自定义验证器,然后为应用程序用户提供一个名为 DisplayName 的额外属性,但这与其说是解决方案,不如说是一种黑客攻击。
我希望我的问题很清楚。提前谢谢。
如果您真的想使用电子邮件地址登录,那么恕我直言,您建议的"黑客"是最好的方法。因为,如果你坚持"正确地做",你至少必须
- 显然修改数据库架构
- 自己确保用户名的唯一性(你可以让数据库约束/索引为你做到这一点,但你必须找到一种处理错误的好方法,并将它们报告给用户)
- 找到一个很好的替代品,只在你的代码中写"User.Identity.UserName"
- 可能更多
另一方面,如果您决定"破解"用户名字段,则需要
- 修改注册视图模型验证(将[电子邮件地址]添加到用户名属性),可能稍微自定义[显示(名称=...)]等。
-
确保 UserManager.UserValidator 实例在帐户控制器中使用允许在电子邮件地址中使用特殊字符。为此,请确保其非默认构造函数如下所示:
public AccountController(UserManager<ApplicationUser> userManager) { UserManager = userManager; var userValidator = UserManager.UserValidator as UserValidator<ApplicationUser>; userValidator.AllowOnlyAlphanumericUserNames = false; }
我希望这可以帮助您权衡这两种方法的优缺点并提出最佳解决方案。祝你好运!
派对有点晚了,但我想我会投入我的 0.02 美元。
虽然 UserName
和 Email
确实都是IdentityUser
的一部分,因此是必需的,但请注意,它们都标记为 virtual
。如果您希望UserName
和Email
成为电子邮件地址,请让 ApplicationUser 模型像这样封装逻辑:
public class ApplicationUser : IdentityUser
{
private string _userNameEmailBackingField;
public override string UserName
{
get { return _userNameEmailBackingField; }
set { _userNameEmailBackingField = value; }
}
public override string Email
{
get { return _userNameEmailBackingField; }
set { _userNameEmailBackingField = value; }
}
//The rest of your ApplicationUser logic
}
然后在视图模型中,仅公开单个属性并将其映射到ApplicationUser
实例中的任/或,确保使用[Required]
和[EmailAddress]
属性修饰视图模型属性。
正如其他人所提到的,您需要确保AllowOnlyAlphanumericUserNames
设置为false
UserManager
的UserValidator
,但是我可以使用VS2013中最新的Web模板开箱即用。
我目前正在为 Identity 1.1 模板开发此功能,该模板将切换到电子邮件并添加帐户确认/忘记密码功能,我们考虑的两个选项是黑客(使用用户名作为带有验证的电子邮件)和添加一个额外的电子邮件字段,该字段与我们倾向于的用户名分开。
在 1.1 中可能会向用户管理器添加一些特定于电子邮件的 API:
FindByEmail
SetEmail
GetEmail
更改 UserManager 对象的 UserValidator 属性:
public class UserManager : UserManager<User>
{
public IUserStore<User> Users { get; private set; }
public UserManager(IUserStore<User> store) : base(store)
{
Users = store;
UserValidator = new UserValidator<User>(this) {AllowOnlyAlphanumericUserNames = false};
}
}
正如您可能已经发现的那样(并且是意料之中的),2014 年 3 月发布的 ASP.NET Identity 2.0.0 在框架中添加了此功能。
公告:http://blogs.msdn.com/b/webdev/archive/2014/03/20/test-announcing-rtm-of-asp-net-identity-2-0-0.aspx
完整示例和教程,包括帐户确认:http://www.asp.net/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity
在处理类似问题时,我发现最简单的解决方案是简单地将用户名输入标记为"电子邮件",然后在创建过程中手动设置会员电子邮件。
protected void RegisterUser_CreatingUser(object sender, LoginCancelEventArgs e){
RegisterUser.Email = RegisterUser.UserName;
}
我得到了这个工作。
首先转到帐户视图模型并为用户名添加属性
Public Class RegisterViewModel
<Required>
<Display(Name:="User Name")>
Public Property UserName As String
<Required>
<EmailAddress>
<Display(Name:="Email")>
Public Property Email As String
修改注册视图后添加用户名属性
<div class="form-group">
@Html.LabelFor(Function(m) m.UserName, New With {.class = "col-md-2 control-label"})
<div class="col-md-10">
@Html.TextBoxFor(Function(m) m.UserName, New With {.class = "form-control"})
</div>
</div>
<div class="form-group">
@Html.LabelFor(Function(m) m.Email, New With {.class = "col-md-2 control-label"})
<div class="col-md-10">
@Html.TextBoxFor(Function(m) m.Email, New With {.class = "form-control"})
</div>
</div>
完成此操作后,也修改您的登录视图
@Html.ValidationSummary(True, "", New With {.class = "text-danger"})
<div class="form-group">
@Html.Label("User Name", New With {.class = "col-md-2 control-label"})
<div class="col-md-10">
@Html.TextBoxFor(Function(m) m.Email, New With {.class = "form-control"})
@Html.ValidationMessageFor(Function(m) m.Email, "", New With {.class = "text-danger"})
</div>
</div>
<div class="form-group">
@Html.LabelFor(Function(m) m.Password, New With {.class = "col-md-2 control-label"})
<div class="col-md-10">
@Html.PasswordFor(Function(m) m.Password, New With {.class = "form-control"})
@Html.ValidationMessageFor(Function(m) m.Password, "", New With {.class = "text-danger"})
</div>
</div>
这就是你所需要的。这样,您可以使用用户名而不是电子邮件地址登录。