ASP .NET  - Agenda de Contatos com Microsoft Access (C#)


Algumas vezes não precisamos usar um canhão para matar uma mosca basta um simples inseticida.

No desenvolvimento de software isso também se aplica afinal é sempre que precisamos usar todo o arsenal que a plataforma .NET nos oferece para realizar uma tarefa bem simples.

Manter as coisas simples é ter bom senso afinal para que complicar.

Neste artigo eu mostro um exemplo de uma aplicação bem simples: uma aplicação ASP .NET que funciona como uma agenda de contatos para uso pessoal.

Ela é bem simples e permite armazenar informações de contatos e realizar a manutenção dessa informações através das operações CRUD: inclui, alterar e excluir.

Neste cenário vamos usar os recursos básicos da plataforma .NET oferecidos na ferramenta Visual Web Developer 2010 Express Edition usando a linguagem C# (eu já publiquei artigos sobre a criação de agenda usando a linguagem VB .NET e VBA)

O banco de dados usado será o Microsoft Access pois a aplicação é de uso pessoal e possuirá um número pequeno de registros.

Criando o banco de dados da aplicação

Podemos criar o banco de dados usando o Microsoft Access. Para isso abra o MS Access e clique no botão Novo e escolha criar um banco de dados vazio informando o nome ContatosDB.mdb;

A seguir vamos criar a tabela Agenda com a seguinte estrutura:

Temos assim um banco de dados com uma tabela bem simples para uso na aplicação ASP .NET.

Criando uma agenda de contatos bem simples

Abra o Visual Web Developer 2010 Express Edition e no menu File clique em New Web Site e selecione o template ASP .NET Empty Web Site informando o nome AgendaMDB e clicando no botão OK;

Como nosso projeto esta vazio vamos incluir um novo Web Form através do menu  WebSite -> Add New Item selecionando o template Web Form e aceitando o nome padrão para o arquivo : Default.aspx;

A seguir vamos incluir uma pasta no projeto através do menu Web Site -> Add ASP .NET Folder -> App_Data;

A pasta App_Data é essencialmente um ponto de armazenamento para armazenamentos de dados baseado em arquivo, como o Microsoft Access. Podemos também incluir arquivos do SQL Server nesta pasta. Estes arquivos terão a anexação automática:

Anexação automática de banco de dados (Auto-Attached DataBases)

Um problema com o ambiente de desenvolvimento que usa banco de dados é a necessidade de ter o SQL Server instalado, onde você precisa anexar o banco de dados , criar um login para o SQL Server e incluir o login no banco de dados. E isto precisa ser feito geralmente em cada máquina de desenvolvimento.(Ou você vai querer que todo mundo esteja logado como Administrador do sistema ?)

O SSE Edition suporta a anexação automática de banco de dados pela inclusão da seguinte string de conexão:

AttacheDbFilename=db.mdf

Com esta string de conexão , o SSE irá automaticamente anexar ao banco de dados quando a aplicação iniciar. Você pode evitar ter que colocar o caminho completo para o banco de dados no seu código usando o novo diretório App_Data e uma característica especial para apontar para ele.

Como exemplo se você estiver usando a seguinte string de conexão:

Data Source=.\SQLEXPRESS; AttachDbFilename=|DataDirectory|db.mdf

A string |DataDirectory| será substituída pelo caminho para o diretório App_Data, evitando assim que você tenha que incluir o caminho completo no seu código.

Nesta pasta será colocado o banco de dados ContatosDB.mdb.

Para fazer isto clique com o botão direito do mouse sobre a pasta e selecione a opção Add Existing Item, selecionando a seguir o banco de dados ContatosDB.mdb. Quando o arquivo é incluído na pasta App_Data ele é também automaticamente incluído no DataBase Explorer.

Nota : Uma dica legal sobre a pasta App_Data que encontrei em : http://www.bufaloinfo.com.br/dicas.aspx?cod=874

Um problema recorrente em muitos fóruns é um problema com o diretório App_Data utilizado em aplicações windows.

A pasta App_Data tem uso típico em aplicações web, mas seu uso não é muito recomendável em aplicações windows.

Uma aplicação windows, quando é executada pelo Visual Studio, é compilada e seu executável copiado para a pasta bin
(podendo variar em uma sub pasta debug ou release).

Ocorre que o banco de dados utilizado na pasta
App_Data também é copiado para dentro da pasta bin.

Consequencia : Todos os dados que você alterar, incluir,deletar enquanto está usando a aplicação serão perdidos na execução seguinte, pois todas as alterações são feitas no banco que está abaixo do Bin, enquanto que na execução seguinte o banco do App_Data será novamente copiado para a pasta abaixo do Bin, apagando os dados.

Isso se tornou uma pergunta muito comum em fóruns, "minha aplicação não está gravando nada !".

Todo esse equívoco tem uma causa e uma solução : As versões express que desenvolvem para windows (VB.NET Express, C# Express, etc.) não fazem acesso direto a um servidor SQL. As versões Express apenas permitem o acesso (usando os wizards, por código tudo pode) a arquivos de dados do SQL Server (
arquivos .MDF) sem vínculo (não attachados) com um servidor.

Para contornar este problema, após criar o arquivo de banco de dados na pasta
App_Data
, copie-o para outro local, fora da pasta do projeto. Faça um vínculo direto ao caminho onde o arquivo estiver.

Fazendo isso o VB irá perguntar se você deseja copiar o arquivo para dentro da sua aplicação (e ainda avisa, em letras miúdas, que isso tem consequencias), basta dizer não para não mais sofrer com este problema com o arquivo de dados.

Dessa forma já temos tudo o que precisamos para criar nossa aplicação ASP .NET : Uma página e um banco de dados.

Definindo o leiaute da página Default.aspx

Vamos definir o leiaute da página Default.aspx conforme a figura abaixo usando os controles:

Devemos configurar o controle AccessDataSource  clicando sobre o controle e selecionando a opção Configure Data Source;

No assistente vamos selecionar o banco de dados ContatosDB.mdb e clicando em Next>;

A seguir vamos selecionar a tabela Agenda e marcar todos os campos;

Clique no botão Advanced e marque a opção : Generate INSERT, UPDATE e DELETE statements;

Ao final o código da página será o seguinte:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AcessoDB.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Inserindo dados em um banco de dados Access</title>
    <style type="text/css">
        .style1
        {
            font-family: "Trebuchet MS";
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <script type="text/javascript">
                function toggle(o) {
                    var e = document.getElementById(o);
                    e.style.display = e.style.display == 'block' ? 'none' : 'block';
                }
                onload = function () {
                    var e, i = 0;
                    while (e = document.getElementById(['list1'][i++])) {
                        e.style.display = 'none';
                    }
                }
            </script>
            <div class="tabledata1">
                <span class="style1">
                <a href="#" onclick="toggle('list1');"><strong>Inserir Novo Registro</strong></a></span>
            </div>
            <div id="list1" style="font-family:Verdana; font-size:11px; background-color:#cccccc; padding:10px;">
                <table>
                    <tr>
                        <td>
                        <hr />
                            <table>
                                <tr>
                                    <td>Nome</td>
                                    <td>Celular</td>
                                    <td>Residencia</td>
                                    <td>Companhia</td>
                                    <td>Email</td>
                                    <td>Empresa</td>
                                    <td>Fax</td>
                                    <td>Nascimento</td>
                                </tr>
                                <tr>
                                    <td><asp:TextBox ID="nome" runat="server" Width="105px"></asp:TextBox></td>
                                    <td><asp:TextBox ID="celular" runat="server" Width="105px"></asp:TextBox></td>
                                    <td><asp:TextBox ID="residencia" runat="server" Width="105px"></asp:TextBox></td>
                                    <td><asp:TextBox ID="companhia" runat="server" Width="105px"></asp:TextBox></td>
                                    <td><asp:TextBox ID="email" runat="server" Width="105px"></asp:TextBox></td>
                                    <td><asp:TextBox ID="empresa" runat="server" Width="105px"></asp:TextBox></td>
                                    <td><asp:TextBox ID="fax" runat="server" Width="105px"></asp:TextBox></td>
                                    <td><asp:TextBox ID="nascimento" runat="server" Width="105px"></asp:TextBox></td>
                                </tr>
                            </table>
                            <div style="text-align: right">
                                <asp:Button ID="btnSubmit" runat="server" Text="Inserir" onclick="btnSubmit_Click" />
                            </div>
                            <hr />
                        </td>
                    </tr>
                </table>
            </div>
        </div>
        <br />
        <div style="font-family:Verdana; font-size:11px; background-color:#c0c0c0; padding:10px;">
            Procurar por&nbsp;
            <asp:DropDownList ID="DropDownList1" runat="server">
            <asp:ListItem>Nome</asp:ListItem>
            <asp:ListItem>Celular</asp:ListItem>
            <asp:ListItem>Residencia</asp:ListItem>
            <asp:ListItem>Companhia</asp:ListItem>
            <asp:ListItem>Email</asp:ListItem>
            <asp:ListItem>Empresa</asp:ListItem>
            <asp:ListItem>Fax</asp:ListItem>
            <asp:ListItem>Nascimento</asp:ListItem>
            </asp:DropDownList>
            &nbsp;
            where like
            &nbsp;
            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
            &nbsp;&nbsp;
            <asp:Button ID="Button1" runat="server" Text="Filtrar" 
                onclick="Button1_Click" />
            &nbsp;&nbsp;&nbsp;
            <asp:Button ID="Button2" runat="server" Text="Limpar Filtro" 
                OnClick="Button2_Click" />
            <br />
            <br />
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
                BackColor="White" BorderColor="White" BorderStyle="Ridge" BorderWidth="2px" 
                CellPadding="3" CellSpacing="1" DataKeyNames="ID" 
                DataSourceID="AccessDataSource1" 
                EmptyDataText="There are no data records to display." GridLines="None" 
                Width="871px" AllowSorting="True">
                <Columns>
                    <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" 
                        ShowSelectButton="True" CancelText="Cancela" DeleteText="Deleta" 
                        EditText="Edita" InsertText="Inserir" NewText="Novo" SelectText="Seleciona" 
                        UpdateText="Atualiza" />
                    <asp:BoundField DataField="Nome" HeaderText="Nome" 
                        SortExpression="Nome" />
                    <asp:BoundField DataField="Celular" HeaderText="Celular" 
                        SortExpression="Celular" />
                    <asp:BoundField DataField="Residencia" HeaderText="Residencia" SortExpression="Residencia" />
                    <asp:BoundField DataField="Companhia" HeaderText="Companhia" 
                        SortExpression="Companhia" />
                    <asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email" />
                    <asp:BoundField DataField="Empresa" HeaderText="Empresa" 
                        SortExpression="Empresa" />
                    <asp:BoundField DataField="Fax" HeaderText="Fax" SortExpression="Fax" />
                    <asp:BoundField DataField="Nascimento" HeaderText="Nascimento" 
                        SortExpression="Nascimento" />
                </Columns>
                <FooterStyle BackColor="#C6C3C6" ForeColor="Black" />
                <HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#E7E7FF" />
                <PagerStyle BackColor="#C6C3C6" ForeColor="Black" HorizontalAlign="Right" />
                <RowStyle BackColor="#DEDFDE" ForeColor="Black" />
                <SelectedRowStyle BackColor="#9471DE" Font-Bold="True" ForeColor="White" />
                <SortedAscendingCellStyle BackColor="#F1F1F1" />
                <SortedAscendingHeaderStyle BackColor="#594B9C" />
                <SortedDescendingCellStyle BackColor="#CAC9C9" />
                <SortedDescendingHeaderStyle BackColor="#33276A" />
            </asp:GridView>
            <asp:AccessDataSource ID="AccessDataSource1" runat="server" 
                DataFile="App_Data\ContatosDB.mdb" 
                DeleteCommand="DELETE FROM `Agenda` WHERE `ID` = ?" 
                InsertCommand="INSERT INTO `Agenda` (`ID`, `Nome`, `Celular`, `Residencia`, `Companhia`, `Email`, `Empresa`, `Fax`, `Nascimento`) 
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)" 
                SelectCommand="SELECT `ID`, `Nome`, `Celular`, `Residencia`, `Companhia`, `Email`, `Empresa`, `Fax`, `Nascimento` FROM `Agenda`" 
                UpdateCommand="UPDATE `Agenda` SET `Nome` = ?, `Celular` = ?, `Residencia` = ?, `Companhia` = ?, `Email` = ?, `Empresa` = ?, `Fax` = ?,
 `Nascimento` = ? WHERE `ID` = ?">
                <DeleteParameters>
                    <asp:Parameter Name="ID" Type="Int32" />
                </DeleteParameters>
                <InsertParameters>
                    <asp:Parameter Name="ID" Type="Int32" />
                    <asp:Parameter Name="Nome" Type="String" />
                    <asp:Parameter Name="Celular" Type="String" />
                    <asp:Parameter Name="Residencia" Type="String" />
                    <asp:Parameter Name="Companhia" Type="String" />
                    <asp:Parameter Name="Email" Type="String" />
                    <asp:Parameter Name="Empresa" Type="String" />
                    <asp:Parameter Name="Fax" Type="String" />
                    <asp:Parameter Name="Nascimento" Type="String" />
                </InsertParameters>
                <UpdateParameters>
                    <asp:Parameter Name="Nome" Type="String" />
                    <asp:Parameter Name="Celular" Type="String" />
                    <asp:Parameter Name="Residencia" Type="String" />
                    <asp:Parameter Name="Companhia" Type="String" />
                    <asp:Parameter Name="Email" Type="String" />
                    <asp:Parameter Name="Empresa" Type="String" />
                    <asp:Parameter Name="Fax" Type="String" />
                    <asp:Parameter Name="Nascimento" Type="String" />
                    <asp:Parameter Name="ID" Type="Int32" />
                </UpdateParameters>
            </asp:AccessDataSource>
        </div>
    </form>
</body>
</html>

Estou usando código JavaScript para esconder e exibir a div do link - Inserir Novo Registro.

    <script type="text/javascript">
                function toggle(o) {
                    var e = document.getElementById(o);
                    e.style.display = e.style.display == 'block' ? 'none' : 'block';
                }
                onload = function () {
                    var e, i = 0;
                    while (e = document.getElementById(['list1'][i++])) {
                        e.style.display = 'none';
                    }
                }
            </script>

Finalmente o código do arquivo code-behind Default.aspx.cs é mostrado abaixo:

using System;
using System.Web.UI.WebControls;
using System.Data.OleDb;
public partial class _Default : System.Web.UI.Page
{
    protected void Button1_Click(object sender, EventArgs e)
    {
        string FilterExpression = string.Concat(DropDownList1.SelectedValue, " LIKE '%{0}%'");
        AccessDataSource1.FilterParameters.Clear();
        AccessDataSource1.FilterParameters.Add(new ControlParameter(DropDownList1.SelectedValue, "TextBox1", "Text"));
        AccessDataSource1.FilterExpression = FilterExpression;
    }
    protected void Button2_Click(object sender, EventArgs e)
    {
        AccessDataSource1.SelectParameters.Clear();
    }
    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        Executar(Convert.ToString(nome.Text), Convert.ToString(celular.Text), Convert.ToString(residencia.Text), Convert.ToString(companhia.Text), 
Convert.ToString(email.Text), Convert.ToString(empresa.Text), Convert.ToString(fax.Text), Convert.ToString(nascimento.Text));
        Response.Redirect("~/AcessoDB.aspx");
    }
    private void Executar(string nome, string celular, string residencia, string companhia , string email, string empresa, string fax, string nascimento)
    {
        try
        {
            string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("App_Data\\ContatosDB.mdb") + ";";
            OleDbConnection conn = new OleDbConnection(connectionString);
            conn.Open();
            OleDbCommand cmd = new OleDbCommand();
            cmd.Connection = conn;
            cmd.CommandText = "INSERT INTO Agenda (Nome, Celular, Residencia, Companhia, Email, Empresa, Fax, Nascimento) VALUES (@nome, @celular, 
@residencia, @companhia, @email, @empresa, @fax, @nascimento)";
            cmd.Parameters.Add("@nome", OleDbType.VarChar).Value = nome;
            cmd.Parameters.Add("@celular", OleDbType.VarChar).Value = celular;
            cmd.Parameters.Add("@residencia", OleDbType.VarChar).Value = residencia;
            cmd.Parameters.Add("@companhia", OleDbType.VarChar).Value = companhia;
            cmd.Parameters.Add("@email", OleDbType.VarChar).Value = email;
            cmd.Parameters.Add("@empresa", OleDbType.VarChar).Value = empresa;
            cmd.Parameters.Add("@fax", OleDbType.VarChar).Value = fax;
            cmd.Parameters.Add("@nascimento", OleDbType.VarChar).Value = nascimento;
            cmd.ExecuteNonQuery();
            conn.Close();
        }
        catch (System.Data.SqlClient.SqlException ex_msg)
        {
            string msg = "Ocorreu um erro durante a inclusão dos dados.";
            msg += ex_msg.Message;
            throw new Exception(msg);
        }
    }
}

 

No código a expressão de filtro é montada com base na seleção do controle Dropdownlist usando a cláusula LIKE:

string FilterExpression = string.Concat(DropDownList1.SelectedValue, " LIKE '%{0}%'");

A função Executar utiliza a instrução SQL INSERT INTO para incluir as informações na tabela Agenda usando os parâmetros obtidos no formulário:

 private void Executar(string nome, string celular, string residencia, string companhia , string email, string empresa, string fax, string nascimento)
    {
        try
        {
            string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("App_Data\\ContatosDB.mdb") + ";";
            OleDbConnection conn = new OleDbConnection(connectionString);
            conn.Open();
            OleDbCommand cmd = new OleDbCommand();
            cmd.Connection = conn;
            cmd.CommandText =
"INSERT INTO Agenda (Nome, Celular, Residencia, Companhia, Email, Empresa, Fax, Nascimento) VALUES (@nome, @celular,
@residencia, @companhia, @email, @empresa, @fax, @nascimento)";

            cmd.Parameters.Add("@nome", OleDbType.VarChar).Value = nome;
            cmd.Parameters.Add("@celular", OleDbType.VarChar).Value = celular;
            cmd.Parameters.Add("@residencia", OleDbType.VarChar).Value = residencia;
            cmd.Parameters.Add("@companhia", OleDbType.VarChar).Value = companhia;
            cmd.Parameters.Add("@email", OleDbType.VarChar).Value = email;
            cmd.Parameters.Add("@empresa", OleDbType.VarChar).Value = empresa;
            cmd.Parameters.Add("@fax", OleDbType.VarChar).Value = fax;
            cmd.Parameters.Add("@nascimento", OleDbType.VarChar).Value = nascimento;
            cmd.ExecuteNonQuery();
            conn.Close();
        }
        catch (System.Data.SqlClient.SqlException ex_msg)
        {
            string msg = "Ocorreu um erro durante a inclusão dos dados.";
            msg += ex_msg.Message;
            throw new Exception(msg);
        }
    }

Executando a aplicação teremos:

1- Execução de filtro pela letra M

2 - Preparação para inclusão de registros e ordenação pela coluna Nome:

E assim para um cenário simples criamos uma solução simples da maneira mais simples possível segundo princípio : KISS - kept it simple stupid.

O projeto completo esta no Super DVD .NET e Super CD .NET.

"E por isso também gememos, desejando ser revestidos da nossa habitação, que é do céu; Se, todavia, estando vestidos, não formos achados nus." II Coríntios 5:2-3

Referências:


José Carlos Macoratti