ASP .NET - Revendo conceitos - Aplicação Currículos web - II


Na primeira parte do artigo definimos o modelo de dados, criamos o projeto ASP  .NET e fizemos ajustes no projeto para criar toda estrutura da aplicação e agora vamos iniciar definindo a página Default.aspx onde é feito o login de um usuário existente e onde também cadastramos um novo usuário.

Definindo a página Default.aspx

Abra a página Default.aspx e no menu Table clique em Insert Table e defina uma tabela com 5 linhas e uma coluna;

A seguir inclua os seguintes controles nesta página:

Distribua os controles conforme o leiaute da figura abaixo:

Como esta página deverá ser a página inicial do projeto selecione a página na janela Solution Explorer e clique com o botão direito do mouse selecionando a opção Set As Start Page.

Nesta página efetuaremos a autenticação de um usuário existente e o cadastro de um novo usuário caso o controle checkbox esteja marcado na página.

O código do arquivo code-behind Default.aspx.cs é mostrado a seguir:

Namespaces definidos na página Default.aspx.cs:

using System;
using
System.Data;
using
System.Data.SqlClient;
using
System.Web.Security;

Variável da página definida para controlar o número de vezes que o usuário pode tentar realizar o login:

static int contador = 0;

Código definido no evento click do botão de comando Login:

protected void btnLogin_Click(object sender, EventArgs e)

{

     if (chkNovoUsuario.Checked)

     {

        CriaNovoUsuarioLogin();

     }

     else

     {

        DoLogin();

     }

}

Neste código temos a chamada de duas rotinas:

1 - Código da rotina DoLogin()

O código da rotina DoLogin é visto a seguir:

  private void DoLogin()
    {
        if (txtUsuario.Text == String.Empty || txtSenha.Text == String.Empty)
        {
            lblMensagem.Text = "Informe o nome e a senha do usuário.";
            return;
        }

        if (txtUsuario.Text.Length < 6 || txtSenha.Text.Length < 6 )
        {
            lblMensagem.Text = "Tamanho mínimo para nome e senha é 6 caracteres.";
            return;
        }
        string senha = FormsAuthentication.HashPasswordForStoringInConfigFile(txtSenha.Text, "SHA1");
        string login = txtUsuario.Text.Trim();
        SqlConnection ConexaoSQL = new SqlConnection(Application["ConexaoDBSQLCurriculos"].ToString());
        try
        {
            if (contador > 3)
            {
                lblMensagem.Text = "Numero de tentativas de login excedidas";
                contador = 0 ;
                Response.Redirect("~/ErroLogin.aspx");
            }
            ConexaoSQL.Open();
            SqlCommand cmdSQL;
            string strSql = "select * from Usuarios where login='" + login + "'";
            cmdSQL = new SqlCommand(strSql, ConexaoSQL);
            SqlDataReader reader = cmdSQL.ExecuteReader();
            bool bEncontrou = false;
            string strSenhaBD = "";
            int nUsuarioID = 0;
            if (reader.Read())
            {
                bEncontrou = true;
                strSenhaBD = Convert.ToString(reader["senha"]).ToUpper();
                nUsuarioID = reader.GetInt32(0);
            }
            reader.Close();
            if (!bEncontrou)
            {
                lblMensagem.Text = "Login não encontrado.";
            }
            else if (strSenhaBD != senha)
            {
                lblMensagem.Text = "Senha Inválida.";
                contador = contador + 1;
            }
            else
            {
                Session["UsuarioID"] = nUsuarioID;
                Response.Redirect("~/Menu.aspx");
            }
        }
        catch (Exception ex)
        {
            lblMensagem.Text = ex.Message.ToString();
        }
        finally
        {
            if (ConexaoSQL.State == ConnectionState.Open)
            {
                ConexaoSQL.Close();
            }
        }
    }

Entendendo o código:

Primeiro verificamos se o usuário e a senha foram informados e se o número mínimo de caracteres informados é maior que 6

A seguir realizamos a criptografia da senha usando o método HashPasswordForStorinfConfigFile() passando o texto da senha informada.

 string senha = FormsAuthentication.HashPasswordForStoringInConfigFile(txtSenha.Text, "SHA1");

Este método produz uma senha de hash adequada para armazenar em um arquivo de configuração com base na senha especificada e o algoritmo de hash.

Nota: Um hash é uma seqüencia de letras ou números geradas por um algoritmo de Hash.

Por este motivo usamos o namespace : using System.Web.Security;

A seguir definimos uma nova conexão usando a string de conexão que é obtida a partir do evento Application_Start do arquivo Global.asax;

 SqlConnection ConexaoSQL = new SqlConnection(Application["ConexaoDBSQLCurriculos"].ToString());

Depois verificamos se o contador excedeu o número de tentativas definidas como 3 redirecionando o usuário para a página ErroLogin.aspx;

            if (contador > 3)
            {
                lblMensagem.Text = "Numero de tentativas de login excedidas";
                contador = 0 ;
                Response.Redirect("~/ErroLogin.aspx");
            }

Na sequência definimos a instrução SQL para selecionar todos os usuários da tabela Usuarios com o login informado e executamos o comando usando o método ExecuteReader();

            ConexaoSQL.Open();
            SqlCommand cmdSQL;
            string strSql = "select * from Usuarios where login='" + login + "'";
            cmdSQL = new SqlCommand(strSql, ConexaoSQL);
            SqlDataReader reader = cmdSQL.ExecuteReader();
            bool bEncontrou = false;
            string strSenhaBD = "";
            int nUsuarioID = 0;

Realizamos a leitura do DataReader gerado e caso o login seja válido armazenamos a senha na variável strSenhaBD e o usuário na variável nUsuarioID;

            if (reader.Read())
            {
                bEncontrou = true;
                strSenhaBD = Convert.ToString(reader["senha"]).ToUpper();
                nUsuarioID = reader.GetInt32(0);
            }

Note que usamos duas formas distintas para obter o valor do datareader :

As duas formas são válidas mas a segunda é mais rápida.

Fechamos o datareader e verificamos se o login é válido; a seguir verificamos se a senha informada confere e incrementamos o contador caso a senha não confira;

Finalmente criamos uma variável de sessão chamada UsuarioID atribuindo à mesma o código do usuário e redirecionamos o usuário para página Menu.aspx;

            reader.Close();
            if (!bEncontrou)
            {
                lblMensagem.Text = "Login não encontrado.";
            }
            else if (strSenhaBD != senha)
            {
                lblMensagem.Text = "Senha Inválida.";
                contador = contador + 1;
            }
            else
            {
                Session["UsuarioID"] = nUsuarioID;
                Response.Redirect("~/Menu.aspx");
            }

2 - Código da rotina CriaNovoUsuarioLogin()

 private void CriaNovoUsuarioLogin()
    {
        if (txtUsuario.Text == String.Empty || txtSenha.Text == String.Empty)
        {
            lblMensagem.Text = "Informe o nome e a senha do usuário.";
            return;
        }
        if (txtUsuario.Text.Length < 6 || txtSenha.Text.Length < 6)
        {
            lblMensagem.Text = "Tamanho mínimo para nome e senha é 6 caracteres.";
            return;
        }
        string senha = FormsAuthentication.HashPasswordForStoringInConfigFile(txtSenha.Text,"SHA1");
        string login = txtUsuario.Text.Trim();
        SqlConnection mConexaoSQL = new SqlConnection(Convert.ToString(Application["ConexaoDBSQLCurriculos"]));
            SqlCommand cmdSQL;
            SqlTransaction transacaoSQL = null;
            try
            {
                mConexaoSQL.Open();
                string strSql = "select * from Usuarios where login='" + login + "'";
                cmdSQL  = new SqlCommand( strSql, mConexaoSQL );
                SqlDataReader reader = cmdSQL.ExecuteReader();
                bool bEncontrou = false;
                if( reader.Read() )
                {
                    bEncontrou = true;
                }
                reader.Close();
                if( bEncontrou )
                {
                    lblMensagem.Text ="O nome do usuário informado já existe.";
                    mConexaoSQL.Close();
                    contador = contador + 1;
                    return;
                }
                transacaoSQL = mConexaoSQL.BeginTransaction( IsolationLevel.ReadCommitted,"NewUser" );
                strSql = "insert into Usuarios (login,senha) VALUES ('" + login + "','" + senha + "') select @usuarioid = @@IDENTITY";
                cmdSQL  = new SqlCommand( strSql, mConexaoSQL, transacaoSQL );
                cmdSQL.Parameters.Add("@usuarioid", SqlDbType.Int);
                cmdSQL.Parameters["@usuarioid"].Direction = ParameterDirection.Output;
                cmdSQL.ExecuteNonQuery();
                int nUsuarioID = Convert.ToInt32( cmdSQL.Parameters["@usuarioid"].Value );
                cmdSQL = new SqlCommand("insert into InfoPessoal (usuarioid) VALUES (" + Convert.ToString(nUsuarioID) + ")", mConexaoSQL, transacaoSQL);
                cmdSQL.ExecuteNonQuery();
                cmdSQL = new SqlCommand("insert into InfoEducacao (usuarioid) VALUES (" + Convert.ToString(nUsuarioID) + ")", mConexaoSQL, transacaoSQL);
                cmdSQL.ExecuteNonQuery();
                cmdSQL = new SqlCommand("insert into InfoProfissional (usuarioid) VALUES (" + Convert.ToString(nUsuarioID) + ")", mConexaoSQL, transacaoSQL);
                cmdSQL.ExecuteNonQuery();
                cmdSQL = new SqlCommand("insert into InfoHabilidades (usuarioid) VALUES (" + Convert.ToString(nUsuarioID) + ")", mConexaoSQL, transacaoSQL);
                cmdSQL.ExecuteNonQuery();
                transacaoSQL.Commit();
                Session["UsuarioID"] = nUsuarioID;
                Response.Redirect( "~/Menu.aspx" );
            }
            catch( Exception ex )
            {
                lblMensagem.Text = ex.Message.ToString();
                if( transacaoSQL != null )
                {
                    transacaoSQL.Rollback();
                }
            }
            finally
            {
                if( mConexaoSQL.State == ConnectionState.Open )
                {
                    mConexaoSQL.Close();
                }
            }
      }

Destaques do código da rotina CriaNovoUsuarioLogin:

Neste código vou destacar a utilização de uma transação definida pela utilização do método BeginTransaction que inicia uma transação usando um nível de isolamento específico definido como ReadCommitted que especifica que bloqueios compartilhados são mantidos enquanto os dados estão sendo lidos para evitar leituras sujas, mas os dados podem ser alterados antes do final da transação, resultando em leituras não repetíveis ou dados fantasmas. Esta opção é o padrão do SQL Server.

Estamos obtendo o número do código do usuário que foi recém incluído na tabela Usuarios  através da definição do comando:  select @usuarioid = @@IDENTITY";

Durante a chamada do método Insert , o banco de dados pode enviar dados de volta a aplicação ADO.NET como parâmetros de saída ou como o primeiro registro retornado como resultado de um comando SELECT executado no mesmo lote como uma instrução INSERT.

Para retornar o valor de um campo identity de uma nova linha incluída no SQL Server usamos uma stored procedure com um parâmetro de saída (OUTPUT Parameter). Para realizar estas tarefas podemos usar três funções Transact-SQL no SQL Server:

Função Descrição
SCOPE_IDENTITY Retorna o último valor identity no escopo da execução atual. (É o recomendado)
@@IDENTITY Contém o último valor identity gerado em qualquer tabela na sessão atual. Pode ser afetado por Triggers e pode não conter o valor identity que você espera.
IDENTI_CURRENT Retorna o último valor identity gerado para uma tabela específica em qualquer sessão e qualquer escopo.
                transacaoSQL = mConexaoSQL.BeginTransaction( IsolationLevel.ReadCommitted,"NewUser" );
                strSql = "insert into Usuarios (login,senha) VALUES ('" + login + "','" + senha + "') select @usuarioid = @@IDENTITY";
                cmdSQL  = new SqlCommand( strSql, mConexaoSQL, transacaoSQL );
                cmdSQL.Parameters.Add("@usuarioid", SqlDbType.Int);
                cmdSQL.Parameters["@usuarioid"].Direction = ParameterDirection.Output;
                cmdSQL.ExecuteNonQuery();
                int nUsuarioID = Convert.ToInt32( cmdSQL.Parameters["@usuarioid"].Value );
                cmdSQL = new SqlCommand("insert into InfoPessoal (usuarioid) VALUES (" + Convert.ToString(nUsuarioID) + ")", mConexaoSQL, transacaoSQL);
                cmdSQL.ExecuteNonQuery();
                cmdSQL = new SqlCommand("insert into InfoEducacao (usuarioid) VALUES (" + Convert.ToString(nUsuarioID) + ")", mConexaoSQL, transacaoSQL);
                cmdSQL.ExecuteNonQuery();
                cmdSQL = new SqlCommand("insert into InfoProfissional (usuarioid) VALUES (" + Convert.ToString(nUsuarioID) + ")", mConexaoSQL, transacaoSQL);
                cmdSQL.ExecuteNonQuery();
                cmdSQL = new SqlCommand("insert into InfoHabilidades (usuarioid) VALUES (" + Convert.ToString(nUsuarioID) + ")", mConexaoSQL, transacaoSQL);
                cmdSQL.ExecuteNonQuery();
                transacaoSQL.Commit();

Depois de obter o valor do código do usuário do campo usuarioid usamos o valor para incluir dados nas demais tabelas da aplicação usando instruções SQL - Insert Into; Inicialmente teremos somente o valor do código do usuário incluído e os demais campos serão todos nulos e poderão ser atualizados posteriormente na opção Editar Currículo.

Para concluir confirmamos a transação realizando um Commit.

Na terceira parte do artigo vamos definir a página Menu.aspx e suas opções para Procurar e Editar um currículo.

Aguarde a continuação em : ASP .NET - Revendo conceitos - Aplicação Currículos web - III

"Toda boa dádiva e todo dom perfeito vêm do alto, descendo do Pai das luzes, em quem não há mudança nem sombra de variação."  Tiago 1:17

Referências:


José Carlos Macoratti