ASP.NET Identity – Nome de usuário no formato de e-mail.

O ASP.NET Identity é altamente customizável, pois foi desenvolvido justamente para ser adaptado em diversos cenários, nesse artigo iremos implementar como permitir que o nome de usuário esteja no formato de e-mail.

 

ASP.NET Identity

Muitos portais e sistemas Web optam por utilizar o próprio e-mail do usuário registrado como nome de usuário, isso proporciona algumas vantagens:

  • Um username a menos para o usuário decorar.
  • Estimula o usuário fornecer um e-mail real.
  • O usuário não precisa se chatear por que seu username escolhido já esta em uso.
  • Usuários não mudam de e-mail com tanta frequência.
  • Um campo a menos para o usuário preencher no cadastro.
  • Os maiores portais utilizam e-mail como username (Facebook, Microsoft, Google, Linkedin, etc…)

Por padrão o ASP.NET Identity não permite que o username possua caracteres especiais, logo o “@” não será permitido, para permitir que o usuário utilize seu e-mail como username será necessário realizar as mudanças a seguir.

*O exemplo a seguir está com base no projeto utilizado no artigo anterior sobre ASP.NET Identity

Método 1

Esse é o método mais rápido de implementar que é desabilitando a validação de caracteres especiais da classe UserManager, é simples e rápido, localize o arquivo Controllers > AccountController.cs, o construtor da controller estará como no código a seguir.

public AccountController(UserManager userManager)
{
    UserManager = userManager;
}

Nesse caso basta criar um novo UserValidator qual possui a propriedade AllowOnlyAlphanumericUserNames que ao ser setada como false permite que outros caracteres sejam utilizados no nome de usuário.

public AccountController(UserManager userManager)
{
    UserManager = userManager;

    // Criando um UserValidator
    UserManager.UserValidator = new UserValidator(UserManager)
    {
        // Desabilitando a regra de apenas caracteres alfanumericos.
        AllowOnlyAlphanumericUserNames = false
    };
}

É funcional mas eu pessoalmente não acho nada elegante.

Método 2

Uma opção mais complexa é criar seu próprio CustomValidator para ser utilizado no momento da validação do username. Para isso sugiro que seja criada uma pasta específica chamada Validators por ex. Nesta pasta crie uma classe chamada CustomUserValidator.cs e utilize o código a seguir.

using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;

namespace DemoIdentity.Validator
{
    public class CustomUserValidator<TUser> : IIdentityValidator<TUser>
        where TUser : class, IUser
    {
        private static readonly Regex EmailRegex = new Regex(@"^[A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        private readonly UserManager<TUser> _manager;

        public CustomUserValidator()
        {
        }

        public CustomUserValidator(UserManager<TUser> manager)
        {
            _manager = manager;
        }

        public async Task<IdentityResult> ValidateAsync(TUser item)
        {
            var errors = new List<string>();
            if (!EmailRegex.IsMatch(item.UserName))
                errors.Add("O endereço de email não é válido.");

            if (_manager != null)
            {
                var otherAccount = await _manager.FindByNameAsync(item.UserName);
                if (otherAccount != null && otherAccount.Id != item.Id)
                    errors.Add("Já existe uma conta utilizando este email, selecione um diferente.");
            }

            return errors.Any()
                ? IdentityResult.Failed(errors.ToArray())
                : IdentityResult.Success;
        }
    }
}

Note que a validação de formato de e-mail é feita através de expressão regular e a classe de validação também verifica se o e-mail já não está cadastrado na base, caso qualquer erro seja encontrado uma mensagem de erro é adicionada à uma lista de mensagens e no final é repassada para o helper Failed da classe IdentityResult.

Para implementar a classe CustomUserValidator basta modificar o construtor da controller AccountController da mesma forma que foi feito no método 1.

public AccountController(UserManager<ApplicationUser> userManager)
{
    UserManager = userManager;

    // Aplicando um UserValidator customizado.
    UserManager.UserValidator = new CustomUserValidator<ApplicationUser>(UserManager);
}

Notem que a classe UserManager que é exposta pelo ASP.NET Identity permite que você utilize uma classe de validação que implemente a interface IIdentityValidator e esta classe pode ser customizada para atender qualquer regra que sua validação exigir.

Desta forma além de mais elegante é possível realizar diversas validações em uma classe exclusivamente responsável por validar o nome de usuário.

Caso esteja utilizando o exemplo iniciado no artigo anterior basta realizar as modificações a seguir.

  1. Remover a propriedade “Email” das classes/arquivos
    • ApplicationUser
    • RegisterViewModel
    • View Account
    • AccountController (método Register)
  2. Utilizar o DataAnnotation [Email] na propriedade UserName da classe RegisterViewModel
  3. Atualizar o banco de dados (usando migrations por ex).

Referências

Este artigo faz parte da série de como customizar diversas funcionalidades no ASP.NET Identity. Aguarde pelos próximos.

Ficou com dúvidas? Quer compartilhar conosco alguma experiência? Utilize os comentários abaixo 😉

Até a próxima.

2 ideias sobre “ASP.NET Identity – Nome de usuário no formato de e-mail.

  1. Obrigado Eduardo.

    Foi muito mais fácil do que eu imaginava. 😉

    Odeio usernames, as pessoas sempre acabam se esquecendo por não ser algo do dia a dia.

  2. No meu caso o metódo 2 não deu certo, pois quando vou declarar:
    UserManager = userManager
    Me ocorre o seguinte erro, *Não é possível converter implicitamente tipo “Microsoft.AspNet.Identity.UserManager” em “Ebase.EmissorNFweb.ApplicationUserManager”. Existe uma conversão explicita(há uma coversão ausente?)

    Como eu posso está resolvendo isso??

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *