ASP .NET MVC - Criando um simples formulário de login

Neste artigo vamos criar uma aplicação ASP .NET MVC 5 que realiza a autenticação em um banco de dados usando um simples formulário de login.

É uma tarefa simples mas para quem esta iniciando com o padrão MVC pode ficar perdido pois tudo mudou em relação ao ASP .NET Web Forms.

A arquitetura/padrão MVC fornece uma maneira de dividir a funcionalidade envolvida na manutenção e apresentação dos dados de uma aplicação. A arquitetura MVC não é nova e foi originalmente desenvolvida para mapear as tarefas tradicionais de entrada , processamento e saída para o modelo de interação com o usuário. Usando o padrão MVC fica fácil mapear esses conceitos no domínio de aplicações Web multicamadas.

O ASP .NET MVC é uma implementação da arquitetura MVC para o ASP .NET em um framework com o objetivo de criar aplicações WEB no padrão MVC e fornecer uma alternativa ao modelo WebForm do ASP .NET disponível até então. O framework ASP .NET MVC fornece um ambiente robusto e leve que esta integrado aos recursos do ASP .NET como master pages e membership sendo definido no namespace System.Web.Mvc e apresenta os seguintes componentes:

Se você pretende criar aplicações ASP .NET MVC tem que se acostumar a pensar diferente pois uma URL não é igual a uma página.

Quando você cria uma aplicação ASP .NET no modelo tradicional usando Web Forms existe uma correspondência direta e única entre uma página e uma URL. Dessa forma, usando este modelo de desenvolvimento,  se você faz uma requisição para uma página chamada Exemplo.aspx, ela deve existir fisicamente no servidor ou caso contrário você irá receber como resposta a mensagem de erro : 404 - Page Not Found.

Ao desenvolver sua aplicação usando o modelo ASP .NET MVC  não existe uma correspondência entre uma URL e uma página, assim , a URL que é invocada pelo navegador  não esta relacionada com a presença obrigatória de arquivos físicos no servidor para exibição do resultado esperado.

No modelo de desenvolvimento ASP .NET MVC uma URL corresponde a um ação de um Controller(Controller Action) e não a uma página em disco.

Veja mais no meu artigo:  Compreendendo Models, Views e Controllers - MVC

Recursos usados

Definindo o banco de dados e a tabela de Usuários

Neste exemplo eu vou usar um banco de dados SQL Server chamado Cadastro.mdf e a tabela Usuarios que contém a seguinte estrutura:

CREATE TABLE [dbo].[Usuarios]
(

   [Id]
INT NOT NULL PRIMARY KEY IDENTITY,
   [NomeUsuario]
NVARCHAR(50) NOT NULL,
   [Senha]
NVARCHAR(50) NOT NULL
)

 

A seguir temos alguns dados que foram incluídos na tabela para efeito de teste:

Criando o projeto ASP .NET MVC

Abra o  Visual Studio 2013 Express for web e clique em New Project;

 

A seguir selecione o template Visual C# -> Web -> ASP .NET Web Application e informe o nome Mvc_Login e clique no botão OK;

 

 

A seguir selecione o template MVC e clique no botão OK;

 

 

Você verá na janela Solution Explorer a estrutura do projeto criado conforme a figura abaixo.

 

 

Apenas para lembrar vamos declarar qual o conteúdo de cada pasta criada na estrutura do projeto:

 

 Pasta  Papel no projeto
 App_Data  Armazena arquivos de dados e informações como um banco de dados SQL Express;
 App_Start  Contém as classes de configuração para inicialização do site MVC com : rotas, autenticação, filtros e Web API
 Content  Contém os arquivos de estilos usados no site;
 Controllers  Contém os controladores usados no site. Os arquivos são nomeados usando a sintaxe; NomeArquivoController
 fonts  Contém as fontes usadas pelos estilos;
 Models  Possui as classes do Model (Um model MVC contém toda a lógica da sua aplicação que não esta contida no Controlador ou na Visão)
 My Project  Possui as referências do projeto
 Scripts  Contém os arquivos de scripts jQuery, BootStrap, etc.
 Views  Contém os arquivos de visualização, páginas HTML, .aspx, etc. Possui subpastas para cada Controlador.

 

Definindo o Model - Criando um Entity Data Model

 

Vamos criar o nosso model que deverá representar o usuário que deseja fazer o login. Para isso clique com o botão direito do mouse sobre a pasta Models e a seguir clique em Add -> New Item;

 

Selecione a guia Data e o template ADO .NET Entity Data Model informando o nome Cadastro.edmx e clique no botão Add;

 

 

Na janela do assistente selecione Generate from Database e clique no botão Next>;

 

Selecione a conexão com o banco de dados onde você definiu a tabela Usuarios. Neste exemplo estou usando o banco de dados Cadastro.mdf;

 

 

Clique no botão Next>;

 

A seguir selecione a tabela Usuarios que foi criada no início deste artigo e aceite o nome padrão para Model e marque as opções conforme mostra a figura abaixo:

 

 

Será mapeada a entidade Usuario e criado modelo de entidades conforme mostra a figura abaixo:

 

 

Vamos abrir o arquivo Usuario.cs gerado pelo Entity Framework e incluir algumas validações usando o Data Annotations;

 

Abaixo vemos a classe Usuario com o código para validação que desejamos usar:

 

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Mvc_login.Models
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    public partial class Usuario
    {
        public int Id { get; set; }
        [Display(Name = "Login")]
        [Required(ErrorMessage = "Informe o nome do usuário", AllowEmptyStrings = false)]
        public string NomeUsuario { get; set; }
        [Required(ErrorMessage = "Informe a senha do usuário", AllowEmptyStrings = false)]
        [DataType(System.ComponentModel.DataAnnotations.DataType.Password)]
        public string Senha { get; set; }
    }
}

Nota: O código em azul foi o código que foi incluído.

Observe que os campos definidos estão decorados com os atributos Required, Display e DataType da Data Annotations.

Os atributos Data Annotation foram introduzido no .NET 3.5 como uma forma de adicionar a validação para as classes usadas por aplicações ASP.NET. Desde aquela época, o RIA Services começou a usar anotações de dados e eles agora fazem parte do Silverlight também.

Para este recurso devemos usar o namespace System.ComponentModel.DataAnnotations pois é ele que provê atributos de classes (usados para definir metadados) e métodos que podemos usar em nossas classes para alterar as convenções padrão e definir um comportamento personalizado que pode ser usado em vários cenários.

A seguir temos a relação das principais Data Annotations :

Key - Usada para especificar que uma propriedade/coluna é parte da chave primária da entidade e se aplica apenas a propriedades escalares;
StringLength - Usada para especificar o tamanho máximo de uma string;
Concurrency - Usada para especificar que uma propriedade/coluna tem um modo de concorrência "fixed " no modelo EDM;
Required : - Usada para especificar que uma propriedade/coluna é não nula e aplica-se a propriedades escalares, complexas, e de navegação;
Column – Usada para especificar o nome da coluna, a posição e o tipo de dados ;
Table – Usada para especificar o nome da tabela e o esquema onde os objetos da classe serão atualizados;
ForeignKey - Usado em uma propriedade de navegação para especificar a propriedade que representa a chave estrangeira da relação
DatabaseGenerated -Usada em uma propriedade para especificar como o banco de dados gera um valor para a propriedade, ou seja, Identity, Computed ou None;
NotMapped – Usada para definir que a propriedade ou classe não estará no banco de dados;

Definindo o comportamento da nossa aplicação

Neste momento se você executar a aplicação será apresentada a view Index que foi gerada por padrão quando da criação da solução MVC. E o fluxo normal será o seguinte:

Esta view é chamada pela Action Index  definida no controlador HomeController.

Mas por que este é o comportamento padrão ? Porque foi configurado assim.

Na pasta App_Start temos o arquivo RouteConfig.cs que define a rota padrão conforme mostra o código abaixo:

using System.Web.Mvc;
using System.Web.Routing;
namespace Mvc_login
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

Observe que o controlador padrão é o HomeController e que a Action padrão é a Action Index.

Vamos alterar esse comportamento, pois queremos que ao iniciar a aplicação seja chamada a Action Login que iremos criar no controlador HomeController.

Vamos alterar o código acima definindo a Action padrão como sendo a Action Login:

using System.Web.Mvc;
using System.Web.Routing;
namespace Mvc_login
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Login", id = UrlParameter.Optional }
            );
        }
    }
}

Após isso na pasta Controllers abra o arquivo HomeController e defina a Action Login conforme abaixo:

 public ActionResult Login()
 {
            return View();
 }

Agora vamos criar a nossa view para o Login a partir da Action Login. Clique com o botão direito no interior da Action Login e a seguir em Add View;

Na janela Add View vamos definir o nome da View como Login definir o template Empty e escolher o Modelo e o data context conforme a figura abaixo:

A seguir vamos incluir o código abaixo no arquivo Login.cshtml criado na pasta Views/Account :

@model Mvc_login.Models.Usuario
@{
    ViewBag.Title = "Login";
}
<h2>Login</h2>
@using (Html.BeginForm("Login", "Home", FormMethod.Post))
{
    //cria a tag do formulário
    @Html.AntiForgeryToken() // previne o ataque CSRF
    @Html.ValidationSummary(true)
    if (@ViewBag.Message != null)
    {
        <div style="border:1px solid red">
            @ViewBag.Message
        </div>
    }
    <table>
        <tr>
            <td>@Html.LabelFor(a => a.NomeUsuario)</td>
            <td>@Html.TextBoxFor(a => a.NomeUsuario)</td>
            <td>@Html.ValidationMessageFor(a => a.NomeUsuario)</td>
        </tr>
        <tr>
            <td> @Html.LabelFor(a => a.Senha)</td>
            <td> @Html.PasswordFor(a => a.Senha) </td>
            <td> @Html.ValidationMessageFor(a => a.Senha) </td>
        </tr>
        <tr>
            <td></td>
            <td>
                <input type="submit" value="Login" />
            </td>
            <td></td>
        </tr>
    </table>
}
@section Scripts{
    @Scripts.Render("~/bundles/jqueryval")
}

Esse será o nosso formulário de Login que será apresentado ao usuário para informar o nome e senha do usuário.

Após o usuário informar o nome e senha do usuário ocorrerá um post que vamos tratar criando uma Action Login no arquivo HomeController.cs definindo outra Action Login que agora recebe os dados postados:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Login(Usuario u)
    {
            // esta action trata o post (login)
            if (ModelState.IsValid) //verifica se é válido
            {
                using (CadastroEntities dc = new CadastroEntities())
                {
                    var v = dc.Usuarios.Where(a => a.NomeUsuario.Equals(u.NomeUsuario) && a.Senha.Equals(u.Senha)).FirstOrDefault();
                    if (v != null)
                    {
                        Session["usuarioLogadoID"] = v.Id.ToString();
                        Session["nomeUsuarioLogado"] = v.NomeUsuario.ToString();
                        return RedirectToAction("Index");
                    }
                }
            }
            return View(u);
  }

 

Observe que estamos validando as informações de nome e senha do usuário consultando o modelo de entidades e se a autenticação for bem sucedida criamos duas variáveis de sessão : usuarioLogadoID e nomeUsuarioLogado e direcionamos o usuário para Action Index.

Na Action Index do controlador HomeController vamos então verificar se o usuário foi autenticado checando se a variável usuarioLogadoID não é nula. Se o login falhar retornamos o usuário para Action Login.

Para fazer isso defina o código a seguir na Action Index:

 public ActionResult Index()
 {
          if (Session["usuarioLogadoID"] != null)
          {
                return View();
          }
           else
          {
                return RedirectToAction("Login");
         }
  }

Nosso fluxo ficou assim:

Agora executando a aplicação teremos a apresentação da página de Login:

E se o login for realizado com sucesso teremos a apresentação da view Index :

 

Pegue o projeto completo aqui: Mvc_login.zip

João 6:37 Todo o que o Pai me dá virá a mim; e o que vem a mim de maneira nenhuma o lançarei fora.

João 6:38 Porque eu desci do céu, não para fazer a minha vontade, mas a vontade daquele que me enviou.

João 6:39 E a vontade do que me enviou é esta: Que eu não perca nenhum de todos aqueles que me deu, mas que eu o ressuscite no último dia.

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

 

             Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter
 

Referências:


José Carlos Macoratti