24

我正在使用新的 ASP.NET 身份 (RTM),我想知道如何继续将注册和登录从用户名更改为电子邮件。

这个想法是我希望我的用户使用他们的电子邮件和密码进行注册(也可以使用外部登录来获取电子邮件),并且他们在顶部设置了一个显示名称/用户名。

我查看了 IdentityUser,我可以看到 UserName 在那里,但是因为它包含在 ASP.Net Identity 中,无法更改。

我知道我可以使用“用户名”作为电子邮件,使用自定义验证器,然后为 ApplicationUser 提供一个名为 DisplayName 的额外属性,但这更像是一种技巧而不是解决方案。

我希望我的问题很清楚。提前致谢。

4

7 回答 7

23

如果您真的想使用电子邮件地址登录,那么,恕我直言,您建议的“黑客”是最好的方法。因为,如果您坚持“正确地做”,您至少必须

  • 修改数据库模式,显然
  • 自己确保用户名的唯一性(您可以为您创建一个数据库约束/索引,但您必须找到一种处理错误并将其报告给用户的好方法)
  • 找到一个很好的替代品,而不是在你的代码中写“User.Identity.UserName”
  • 可能更多

另一方面,如果您决定“破解” UserName 字段,您需要

  • 修改 RegisterViewModel 验证(将 [EmailAddress] 添加到 UserName 属性),可能稍微自定义 [Display(Name=...)] 等。
  • 确保 AccountController 中使用的 UserManager.UserValidator 实例允许在电子邮件地址中使用特殊字符。为此,请确保其非默认构造函数如下所示:

    public AccountController(UserManager<ApplicationUser> userManager)
    {
        UserManager = userManager;
        var userValidator = UserManager.UserValidator as UserValidator<ApplicationUser>;
        userValidator.AllowOnlyAlphanumericUserNames = false;
    }
    

我希望这可以帮助您权衡两种方法的优缺点并提出最佳解决方案。祝你好运!

于 2013-10-21T12:21:24.337 回答
10

派对迟到了,但我想我会投入 0.02 美元。

UserName虽然and确实Email是其中的一部分,IdentityUser因此是必需的,但请注意它们都标记为virtual. 如果您想成为电子邮件地址UserNameEmail让 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其设置falseUserManager's UserValidator,但我使用 VS2013 中的最新 Web 模板开箱即用。

于 2014-12-02T18:57:44.873 回答
6

我目前正在为 Identity 1.1 模板开发此功能,该模板将切换到电子邮件并添加帐户确认/忘记密码功能,我们考虑的两个选项是 hack(使用用户名作为电子邮件进行验证)和添加一个额外的电子邮件字段这与我们倾向于使用的用户名是分开的。

1.1 中可能会在 UserManager 中添加一些特定于电子邮件的 api:

FindByEmail
SetEmail
GetEmail
于 2013-10-21T21:36:05.427 回答
5

更改 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};
    }
}
于 2013-10-21T13:13:46.980 回答
3

您可能已经发现(并且意料之中),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

于 2014-06-17T07:58:09.243 回答
1

在处理类似问题时,我发现最简单的解决方案是将用户名输入标记为“电子邮件”,然后在 onCreating 期间手动设置会员电子邮件。

protected void RegisterUser_CreatingUser(object sender, LoginCancelEventArgs e){
    RegisterUser.Email = RegisterUser.UserName;            
}
于 2015-07-31T01:26:53.647 回答
0

我得到这个工作。

首先去 accountViewModels 并为 UserName 添加一个 Property

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>

这就是你所需要的。这样您就可以使用用户名而不是电子邮件地址登录。

于 2015-04-10T17:22:23.077 回答