Имя пользователя ASP.Net для отправки по электронной почте

Я работаю с новой версией ASP.NET Identity (RTM), и мне было интересно, как я могу изменить регистрацию и вход в систему с имени пользователя на адрес электронной почты.

Идея состоит в том, что я хочу, чтобы мои пользователи регистрировались, используя свою электронную почту и пароль (электронную почту также можно получить с помощью внешнего входа), и они настраивали отображаемое имя / имя пользователя сверху.

Я посмотрел на IdentityUser и вижу, что UserName там, но поскольку он упакован в ASP.Net Identity, который нельзя изменить.

Я знаю, что могу использовать UserName в качестве электронной почты с настраиваемым валидатором, а затем иметь дополнительный атрибут для ApplicationUser под названием DisplayName, но это скорее взлом, чем решение.

Надеюсь, мой вопрос ясен. Заранее спасибо.


person teh0wner    schedule 20.10.2013    source источник
comment
На данном этапе, похоже, нет другого подхода к реализации. У вас есть правильная информация, и мы продолжим. Framework не предоставляет настраиваемую возможность сделать электронную почту в качестве имени пользователя, как в более ранних версиях членства.   -  person jd4u    schedule 21.10.2013
comment
Для этого Хоа Кунг, разработчик из группы ASP.NET, работающий над Личность. stackoverflow.com/a/19460800/1138263   -  person Dragonseer    schedule 23.10.2013
comment
возможный дубликат stackoverflow.com/questions/19460078/   -  person LiamGu    schedule 07.01.2014
comment
Используя MVC5 и Identity 2.0, вы по умолчанию получаете адрес электронной почты вместо имени пользователя. Если вы, как и я, пришли сюда, чтобы получить имя пользователя вместо электронной почты, я сделал здесь предложение - stackoverflow.com/a/28602436/892018 < / а>   -  person Hoody    schedule 19.02.2015


Ответы (7)


Если вы действительно хотите использовать адрес электронной почты для входа в систему, то, IMHO, предложенный вами «взлом» - лучший подход. Потому что, если вы настаиваете на том, чтобы «делать это правильно», вам придется как минимум

  • изменить схему базы данных, очевидно
  • убедитесь в уникальности имени пользователя (вы можете сделать это за вас с помощью ограничения / индекса базы данных, но вам нужно будет найти хороший способ справиться с ошибками и сообщить о них пользователю)
  • найти хорошую замену просто написанию "User.Identity.UserName" в вашем коде
  • возможно даже больше

С другой стороны, если вы решили «взломать» поле UserName, вам необходимо

  • изменить проверку RegisterViewModel (добавить [EmailAddress] в свойство UserName), возможно, немного настроить [Display (Name = ...)] и т. д.
  • убедитесь, что экземпляр UserManager.UserValidator, используемый в вашем AccountController, допускает использование специальных символов в адресах электронной почты. Для этого убедитесь, что его конструктор не по умолчанию выглядит так:

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

Я надеюсь, что это поможет вам взвесить плюсы и минусы обоих подходов и придумать лучшее решение. Удачи!

person rootless    schedule 21.10.2013
comment
Что делать, если вы используете настраиваемый первичный ключ для своего ApplicationUser? Если моим пользователем приложения является ApplicationUser: IdentityUser ‹int, CustomUserLogin, CustomUserRole, CustomUserClaim› и ваш ApplicationUserManager: UserManager ‹ApplicationUser, int›, указанный выше код UserValidator работать не будет. Если я попробую UserValidator ‹ApplicationUser, int› (manager), он больше не захочет принимать мой пользовательский менеджер. - person Vesselin Obreshkov; 13.03.2014

Немного поздно на вечеринку, но я подумал, что брошу свои 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.

person joelmdev    schedule 02.12.2014
comment
Очень интересное и чистое решение. - person Zapnologica; 07.04.2015
comment
Я люблю такие ответы! элегантно, шустро и просто работает! - person Korayem; 19.04.2016
comment
Спасибо @Korayem. У этого решения определенно есть побочные эффекты, которые некоторые не одобрили бы, но с прагматической точки зрения я думаю, что это приемлемо для этого приложения. - person joelmdev; 19.04.2016
comment
@Korayem изменение имени пользователя при обновлении электронной почты и наоборот, безусловно, является побочным эффектом, но это побочные эффекты, с которыми я могу жить. - person joelmdev; 21.04.2016
comment
У меня была ситуация, когда поле UserName содержало некоторые данные, которые нельзя было переместить. Я просто добавил public override string UserName { get { return Email; } }, чтобы имя пользователя выводилось из поля электронной почты. Другое решение заключалось в сопоставлении поля в конфигурации AppDB, чтобы изменить имя столбца, с которым было связано свойство. - person petrosmm; 25.05.2017

В настоящее время я работаю над этой функцией для шаблонов Identity 1.1, которые переключатся на электронную почту и добавят функцию подтверждения учетной записи / забытого пароля, и двумя вариантами, которые мы рассмотрели, были взлом (использовать имя пользователя в качестве электронной почты с проверкой) и добавление дополнительного поля электронной почты который отличается от имени пользователя, к которому мы склоняемся.

Вполне вероятно, что в UserManager в версии 1.1 будет добавлено несколько API-интерфейсов для электронной почты:

FindByEmail
SetEmail
GetEmail
person Hao Kung    schedule 21.10.2013
comment
Итак, в 1.1 эта пара функций будет включена, если я правильно понял? - person teh0wner; 22.10.2013
comment
Только что обновил свой пакет NuGet в тестовом проекте до версии 1.1, и я действительно вижу в Usemanager несколько методов и атрибутов для сброса пароля, однако я не вижу ничего, что «заменяет» UserName на Email? Кроме того, есть ли ожидаемое время выхода версии 1.1? И насколько сложно будет перейти с 1.0 на 1.1, если я продолжу разработку с 1.0, пока 1.1 не выйдет - person teh0wner; 22.10.2013
comment
В настоящее время нет плана для чего-то вроде UseEmailAsUserName, это то, что мы можем рассмотреть для добавления для реализации EF по умолчанию, не должно быть каких-либо серьезных критических изменений между 1.0 и 1.1, поэтому миграция должна быть довольно простой (надеюсь, просто потребуется Только миграция EF) - person Hao Kung; 22.10.2013
comment
Когда это будет добавлено в ночную сборку? Его нет в пакетах 1.1.0-alpha1-131024 (предварительная версия). Не могли бы вы рассказать, как это будет работать? Будут ли у нас отдельные поля для имени пользователя и электронной почты или поле имени пользователя станет адресом электронной почты? - person Scott Dorman; 24.10.2013
comment
Электронная почта будет отдельным полем в IdentityUser, и приложение будет решать, относиться ли к ним одинаково или нет. Он будет в ночной сборке где-то на следующей неделе. - person Hao Kung; 24.10.2013
comment
Итак, если я хочу рассматривать электронную почту и имя пользователя как одно и то же, могу ли я установить это свойство или потребуется дополнительная работа (например, изменение UserValidator)? Я буду следить за ночными сборками, когда это появится. - person Scott Dorman; 26.10.2013
comment
@HaoKung: Есть документация по этой функции и как ее использовать? - person DeepSpace101; 20.05.2014

Измените свойство UserValidator для вашего объекта UserManager:

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};
    }
}
person avalla    schedule 21.10.2013
comment
Совершенно не имеет отношения к теме. - person Arash; 08.02.2014
comment
@Arash Как так? Решил проблему на отлично. - person rism; 10.03.2014

Как вы, вероятно, узнали (и этого следовало ожидать), ASP.NET Identity 2.0.0, выпущенный в марте 2014 года, добавляет эту функциональность в структуру.

Объявление: 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

person Vincent Sels    schedule 17.06.2014

Работая над аналогичной проблемой, я обнаружил, что самое простое решение - просто пометить поле ввода имени пользователя как «Электронная почта», а затем вручную установить адрес электронной почты для участников во время onCreating.

protected void RegisterUser_CreatingUser(object sender, LoginCancelEventArgs e){
    RegisterUser.Email = RegisterUser.UserName;            
}
person atjoedonahue    schedule 31.07.2015

У меня это работает.

Сначала перейдите в accountViewModels и добавьте свойство для имени пользователя.

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>

Это все, что вам нужно. Таким образом, вы можете войти в систему с именем пользователя, а не с адресом электронной почты.

person Rogerio Picilli    schedule 10.04.2015