ASP .NET - Criando um Álbum de Fotos (C#)


Neste artigo eu vou criar um álbum de fotos usando os recursos básicos da ASP .NET e a linguagem C#. Este é um artigo para iniciantes.

Nosso objetivo será criar um pequeno projeto que permita incluir e visualizar imagens de um banco de dados SQL Server em um site ASP .NET.

Para isso eu vou precisar de um projeto ASP .NET para criar a interface com o usuário e de um banco de dados para armazenar as imagens.

Logo os recursos usados no projeto serão:

Criando o projeto WEB

Abra o VWD e no menu File clique em New Project;

Selecione a linguagem Visual C# o Item Web e marque o template ASP .NET Web Application informando o nome Album_Fotos e clicando em OK;

Será criado um projeto contendo uma estrutura pronta que usa uma master page e outros recursos como autenticação.

Vamos ajustar a estrutura para o nosso exemplo excluindo a pasta Account, visto que não vamos autenticar o usuário, e alterar o arquivo Site.Master conforme abaixo:

......
         </div>
            <div class="clear hideSkiplink">
                <asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" EnableViewState="false" IncludeStyleBlock="false" Orientation="Horizontal">
                    <Items>
                        <asp:MenuItem NavigateUrl="~/Default.aspx" Text="Home"/>
                        <asp:MenuItem NavigateUrl="~/About.aspx" Text="About"/>
                        <asp:MenuItem NavigateUrl="~/Incluir.aspx" Text="Incluir Foto"/>
                        <asp:MenuItem NavigateUrl="~/Exibir.aspx" Text="Exibir Fotos"/>
                    </Items>
                </asp:Menu>
            </div>
......

O código destacado em azul foi incluído de forma a exibir duas novas opções na master page: Incluir Foto e Exibir Fotos.

Vamos ajustar as página Default.aspx e a página About.aspx alterando o texto das páginas.

Ao final desse processo as página Default.aspx e About.aspx deverão ter o leiaute conforme mostra a figura abaixo:

 
 

Definindo o Banco de dados

No menu Project clique em Add New Item e selecione o template Data e a seguir SQL Server Database;

Informe o nome Album.mdf e clique no botão Add;

Será apresentada a mensagem abaixo informando que estamos incluindo um arquivo .mdf em um site ASP .NET e sugerindo que o arquivo criado seja colocado na pasta App_Data;

Clique no botão Sim e aceite a sugestão de forma a criar uma pasta App_Code no projeto e o arquivo Album.mdf ser copiado para esta pasta;

Com o banco de dados criado abra a pasta App_Code e clique duas vezes sobre o arquivo Album.mdf para abri-lo na janela DataBase Explorer;

Expanda os itens da conexão Album.mdf e clique com o botão direito sobre o item Tables e clique em Add New Table;

Defina na tabela uma estrutura contendo os campos conforme mostrados a seguir e salve a tabela com o nome Fotos;

Note que o campo id da tabela Fotos é uma chave primária do tipo identity.

Ao final deveremos ter no arquivo web.config a string de conexão definida da seguinte forma:


.......
 <connectionStrings>
    <add name="ConexaoSQLFotos" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\album.mdf;User Instance=true"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
...........

Criando as páginas do web site

Vamos criar 3 novas páginas em nossa solução que definirão as funcionalidades que desejamos ter na aplicação.

No menu Project clique em Add New Item, selecione o template Web -> Web Form e informe o nome Incluir.aspx e clique no botão Add;

Repita o procedimento e da mesma forma inclua as páginas : Exibir.aspx e Imagem.aspx;

Ao final teremos as páginas :

Incluindo imagens

Vamos agora definir o leiaute da página Incluir.aspx

Selecione e abra a página Incluir.aspx e no menu Table clique em Insert Table;

Vamos definir uma tabela com 6 linhas(rows) e 2 colunas(Columns);

A partir da ToolBox vamos incluir os seguintes controles na tabela:

O código fonte desta página deverá ser o seguinte:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Incluir.aspx.cs" Inherits="Album_Fotos.Incluir" %>
<!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></title>
    <style type="text/css">
        .style1
        {width: 37%;}
        .style2
        {   font-family: "Trebuchet MS";font-size: xx-large;            color: #FFFF00;
            text-align: center;
        }
        .style3
        { font-family: "Trebuchet MS";}
        .style4
        {width: 555px;}
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <table class="style1">
            <tr>
                <td colspan="2" bgcolor="#006699" class="style2">
                    <strong style="text-align: center">Macoratti.net - Incluir Fotos</strong></td>
            </tr>
            <tr>
                <td class="style3">
                    &nbsp;Imagem</td>
                <td class="style4">
                    <asp:FileUpload ID="fupFoto" runat="server" Width="274px" />
                    <asp:CustomValidator ID="cusVal" runat="server" 
                        onservervalidate="cusVal_ServerValidate" style="font-family: 'Trebuchet MS'"></asp:CustomValidator>
                </td>
            </tr>
            <tr>
                <td class="style3">
                    Mensagem</td>
                <td class="style4">
                    <asp:TextBox ID="txtMensagem" runat="server" Height="120px" TextMode="MultiLine" 
                        Width="443px"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td class="style3">
                    Data</td>
                <td class="style4">
                    <asp:TextBox ID="txtData" runat="server" Width="432px" BackColor="#FFFFE6"></asp:TextBox>
                    <asp:Calendar ID="calFoto" runat="server" Height="143px" Width="442px" 
                        onselectionchanged="calFoto_SelectionChanged">
                    </asp:Calendar>
                </td>
            </tr>
            <tr>
                <td colspan="2" style="text-align: center">
                    <asp:Label ID="lblmsg" runat="server" style="font-family: 'Trebuchet MS'"></asp:Label>
                </td>
            </tr>
            <tr>
                <td colspan="2" style="text-align: center">
                    <asp:Button ID="btnEnviar" runat="server" onclick="btnEnviar_Click" 
                        style="text-align: center" Text="Enviar " Width="131px" />
                    <asp:Button ID="btnRetornar" runat="server" onclick="btnRetornar_Click" 
                        Text="Retornar" Width="112px" />
                </td>
            </tr>
        </table>
    </div>
    </form>
</body>
</html>

No arquivo code-behind Incluir.aspx.vb vamos incluir o código abaixo:

using System;
using System.Web;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace Album_Fotos
{
    public partial class Incluir : System.Web.UI.Page
    {
        protected void calFoto_SelectionChanged(object sender, EventArgs e)
        {
            //exibe a nova data selecionada no textbox
            txtData.Text = calFoto.SelectedDate.ToShortDateString();
        }

        protected void cusVal_ServerValidate(object source, ServerValidateEventArgs args)
        {
            //cria um array de extensões válidas
            string[] validaExtensao = { "jpg", "jpeg", "png", "gif", "bmp" };

            //define args como inválida
            args.IsValid = false;

            //pega o nome do arquivo
            string nomeArquivo = fupFoto.PostedFile.FileName;

            //verifica se a string não é vazia
            if (!string.IsNullOrEmpty(nomeArquivo))
            {
                //pega a extensão do arquivo
                string fileExt = nomeArquivo.Substring(nomeArquivo.LastIndexOf('.') + 1).ToLower();
                //verifica se a extensão atual é válida
                for (int i = 0; i < validaExtensao.Length; i++)
                {
                    if (fileExt == validaExtensao[i]) //se for valida
                        args.IsValid = true;               //valida
                }
            }
        }

        protected void btnEnviar_Click(object sender, EventArgs e)
        {
            //verifica se o arquivo selecionado foi selecionado
            if (fupFoto.PostedFile != null && !string.IsNullOrEmpty(fupFoto.PostedFile.FileName) && cusVal.IsValid)
            {
                //cria um array de bytes para armazenar os dados da imagem
                byte[] imgFoto = new byte[fupFoto.PostedFile.ContentLength];
                //armazena o arquivo selecionado na memória
                HttpPostedFile img = fupFoto.PostedFile;
                //define os dados binários
                img.InputStream.Read(imgFoto, 0, (int)fupFoto.PostedFile.ContentLength);

                //conecta com o banco de dados
                SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConexaoSQLFotos"].ConnectionString);

                //salva a imagem no banco de dados
                SqlCommand cmd = new SqlCommand("INSERT INTO Fotos(imagem, tamanho, tipo, data, mensagem) 
                                                                           VALUES (@imagem, @tamanho, @tipo, @data, @mensagem)", conn);
                cmd.CommandType = CommandType.Text;

                //inclui os dados binários
                cmd.Parameters.Add("@imagem", SqlDbType.Image, imgFoto.Length).Value = imgFoto;
                //inclui o tamanho da imagem
                cmd.Parameters.AddWithValue("@tamanho", imgFoto.Length);
                //inclui o tipo da imagem
                cmd.Parameters.AddWithValue("@tipo", fupFoto.PostedFile.ContentType);
                //inclui a data dataa
                cmd.Parameters.AddWithValue("@data", DateTime.Parse(txtData.Text));
                //inclui uma mensagem
                cmd.Parameters.AddWithValue("@mensagem", txtMensagem.Text);

                using (conn)
                {
                    //abre a conexão 
                    conn.Open();
                    //envia a consulta SQL para o banco de dados
                    cmd.ExecuteNonQuery();
                }
                lblmsg.Text = " Imagem enviado com sucesso...";
            }
            else
            {
                lblmsg.Text = "Informações inválidas...";
            }
        }

        protected void btnRetornar_Click(object sender, EventArgs e)
        {
            Response.Redirect("Default.aspx");
        }
    }
}

Executando o projeto teremos a página Default.aspx exibindo as opções do menu e clicando no menu Incluir Foto teremos a exibição da página Incluir.aspx conforme abaixo à direita:

Exibindo Imagens

Abaixo temos o leiaute da página Exibir.aspx. Nela temos o controle Repeater onde vinculamos os campos Imagem, mensagem e data.

A partir da Toolbox inclua um controle Repeater nesta página ID=Repeater1 e configure o controle com um ItemTemplate conforme mostrado ao lado da figura do leiaute:

<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">
    <HeaderTemplate>
        <table border="1" cellpadding="5px">
    </HeaderTemplate>
    <ItemTemplate>
            <!-- Imagem -->
            <tr>
                <td colspan="3">
                    <asp:Image ID="Image1" runat="server" ImageUrl='<%# Eval("id", "~/Imagem.aspx?id={0}") %>'  Width = '80' Height='80' />
                </td>
            </tr>
            <!-- Mensagem/Data/ Link para exibir -->
            <tr>
                <td>
                    <%# Eval("mensagem") %>
                </td>
                <td>
                    <%#Eval("data", "{0:d}")%>
                </td>
                <td>
                   <asp:HyperLink ID="HyperLink1" NavigateUrl ='<%# Eval("id", "~/Imagem.aspx?id={0}") %>'  runat="server" Text="Exibir Imagem" />
               </td>
            </tr>
    </ItemTemplate>
 
    <FooterTemplate>
        </table>
    </FooterTemplate>
</asp:Repeater>

No ItemTemplate do controle Repeater definimos uma tabela onde vinculamos o campo mensagem, data e criamos um hiperlink usando o controle Hyperlink que chama a página Imagem.aspx e passa como parâmetro o código da imagem (id).

Incluímos também um controle SqlDataSource(ID=SqlDataSource1) onde configuramos uma conexão com o banco de dados Album.mdf acessando todos os campos da tabela Fotos

A seguir atribuímos a propriedade DataSourceID do controle Repeater com o id do SqlDataSource que é : SqlDataSource1

O código completo do arquivo Exibir.aspx é o seguinte:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Exibir.aspx.cs" Inherits="Album_Fotos.Exibir" %>

<!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>Exibindo Fotos</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1"  onitemdatabound="Repeater1_ItemDataBound">
    <HeaderTemplate>
        <table border="1" cellpadding="5px">
    </HeaderTemplate>
    <ItemTemplate>
            <!-- Imagem -->
            <tr>
                <td colspan="3">
                    <asp:Image ID="Image1" runat="server" ImageUrl='<%# Eval("id", "~/Imagem.aspx?id={0}") %>'  Width = '80' Height='80' />
                </td>
            </tr>
            <!-- Mensagem/Data/ Link para exibir -->
            <tr>
                <td>
                    <%# Eval("mensagem") %>
                </td>
                <td>
                    <%#Eval("data", "{0:d}")%>
                </td>
                <td>
                   <asp:HyperLink ID="HyperLink1" NavigateUrl ='<%# Eval("id", "~/Imagem.aspx?id={0}") %>'  runat="server" Text="Exibir Imagem" />
               </td>
            </tr>
    </ItemTemplate>
 
    <FooterTemplate>
        </table>
    </FooterTemplate>
</asp:Repeater>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
    ConnectionString="<%$ ConnectionStrings:ConexaoSQLFotos %>" 
    SelectCommand="SELECT * FROM [Fotos]"></asp:SqlDataSource>
        <asp:Button ID="btnRetornar" runat="server" onclick="btnRetornar_Click" 
            Text="Retornar" Width="162px" />
    </div>
    </form>
</body>
</html>

O arquivo code-behind Exibir.aspx.vb tem o seguinte código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Album_Fotos
{
    public partial class Exibir : System.Web.UI.Page
    {
        protected void btnRetornar_Click(object sender, EventArgs e)
        {
            Response.Redirect("Default.aspx");
        }
    }
}

Executando o projeto e clicando no menu Exibir Fotos iremos obter a seguinte página:

Exibindo uma imagem

A página Imagem.aspx terá somente o código no seu arquivo code-behind Imagem.aspx.vb conforme abaixo:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace Album_Fotos
{
    public partial class Imagem : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //verifica se existe uma querystring valida
            if (!string.IsNullOrEmpty(Request.QueryString["id"].ToString()))
            {
                //conecta com o banco de dados
                SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConexaoSQLFotos"].ConnectionString);

                //seleciona uma imagem
                SqlCommand cmd = new SqlCommand("SELECT * FROM Fotos WHERE id=@ImgId", conn);
                cmd.CommandType = CommandType.Text;

                //inclui o id da imagem obtido da query string
                cmd.Parameters.AddWithValue("@ImgId", Request.QueryString["id"]);

                using (conn)
                {
                    //abra a conexão
                    conn.Open();
                    //evia a consulta para selecionar a imagem 
                    SqlDataReader rdr = cmd.ExecuteReader();
                    //le os dados
                    if (rdr.Read())
                    {
                        //armazena os dados binarios em um byte array
                        byte[] imgDados = (byte[])rdr["imagem"];
                        //exibe a imagem
                        Response.ContentType = rdr["tipo"].ToString();
                        Response.OutputStream.Write(imgDados, 0, imgDados.Length);
                    }
                }
            }
        }
    }
}

Este código irá receber o id da imagem selecionando-a da tabela Fotos e exibindo na página no seu tamanho natural:

Assim temos um singelo álbum de fotos bem básico. Você pode incrementar o projeto com diversas funcionalidades.

Pegue o projeto completo aqui:  Album_Fotos.zip

Heb 1:1 Havendo Deus antigamente falado muitas vezes, e de muitas maneiras, aos pais, pelos profetas,

Heb 1:2 nestes últimos dias a nós nos falou pelo Filho, a quem constituiu herdeiro de todas as coisas, e por quem fez também o mundo;

Heb 1:3 sendo ele o resplendor da sua glória e a expressa imagem do seu Ser, e sustentando todas as coisas pela palavra do seu poder, havendo ele mesmo feito a purificação dos pecados, assentou-se à direita da Majestade nas alturas,

Heb 1:4 feito tanto mais excelente do que os anjos, quanto herdou mais excelente nome do que eles.

Referências:


José Carlos Macoratti