ASP .NET - Recuperando imagens em um Banco de dados SQL Server (C#)


Em meu artigo  ASP .NET - Salvando imagens em um banco de dados SQL Server (C#)  eu  mostrei como salvar imagens(dados binários) em um banco de dados SQL Server com C# e para complementar o artigo vou mostrar como recuperar imagens(dados binários) de um banco de dados SQL Server usando C#.

Nota: Dados binários podem se apresentar em uma variedade de formas como : documentos do word, arquivos PDF, Fotos , imagens , etc.

Eu vou aproveitar o artigo anterior que foi criado no Visual Web Developer 2008 Express Editon. Veja abaixo a interface que criamos para enviar uma imagem e salvá-la na tabela Imagens do banco de dados  Fotos.mdf que criamos para este fim.

Executando o projeto teremos o formulário web Default.aspx apresentado e informando o nome da imagem, e clicando no botão Arquivo podemos selecionar uma imagem;

Após isso basta clicar no botão Enviar para salvar o arquivo no banco de dados;

Abrindo a tabela Imagens podemos constatar a imagem salva;

Com isso vemos que salvar imagens em um banco de dados SQL Server usando ASP .NET é uma tarefa bem simples.

Existem muitas alternativas que podemos usar para recuperar a imagem salva no banco de dados e exibi-la em uma página web. A mais simples seria incluir um componente Hiperlink na página que já criamos para salvar a imagem e partir do Hiperlink abrir uma outra página para exibir a imagem salva.

O nosso formulário vai ficar assim exibindo o controle Hiperlink com o ID=hplnkExibeImagem e o texto: Clique aqui para Exibir a Imagem;

Agora teremos que efetuar algumas alterações no código usando no exemplo para salvar a imagem. Vejamos:

1- Abaixo temos o código usando para salvar a imagem no banco de dados (omiti o restante do código para facilitar a leitura):

   protected void btnEnviar_Click(object sender, EventArgs e)
    {
          ...
         ...  
	    using (SqlConnection Conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
	    {
		    try
		    {
			    const string SQL = "INSERT INTO [Imagens] ([nomeArquivo], [horaUpload], [MIME], [imagem]) VALUES _
                                                                                               (@nomeArquivo, @horaUpload, @MIME, @imagem)";

			    SqlCommand cmd = new SqlCommand(SQL, Conn);
                                                    cmd.Parameters.AddWithValue("@nomeArquivo", txtNomeArquivo.Text.Trim());
			    cmd.Parameters.AddWithValue("@MIME", fileType);

                                                     byte[] imageBytes = new byte[fupld.PostedFile.InputStream.Length + 1];

                                                    fupld.PostedFile.InputStream.Read(imageBytes, 0, imageBytes.Length);

			    cmd.Parameters.AddWithValue("@imagem", imageBytes);
			    cmd.Parameters.AddWithValue("@horaUpload", DateTime.Now);

                                                   lblmsg.Text = "<br />Arquivo enviado com sucesso <br />";

			    Conn.Open();
			    cmd.ExecuteNonQuery();
			    Conn.Close();
		    }
		    catch
		    {
		                 lblmsg.Text = "Erro ao enviar imagem";   
                                                 Conn.Close();
		    }
         ......
    }

Para podermos recuperar a imagem no banco de dados temos que obter o seu código que é o identificado pelo campo id da tabela Imagens.

Para recuperar o id da última imagem salva vamos usar o método SELECT SCOPE IDENTITY() e a seguir usando o id recuperado vamos usar o método ExcecuteScalar para retornar o id salvando em uma variável e atribuindo o seu valor ao hiperlink que faz a chamada à página para exibir a imagem.


No SQL Server após você realizar uma operação de inclusão de dados via INSERT , SELECT INTO ou uma cópia em massa (BULKY COPY) em uma tabela com uma coluna IDENTITY, a variável global @@IDENTITY conterá o último valor da identidade que é gerado pela instrução. (Se nenhuma coluna for sensibilidade será retornado NULL). Se múltiplas linhas tiverem sido incluídas , gerando múltiplos valores identidade(IDENTITY) o último será retornado.

Para obter o último valor identidade gerado nestes casos  podemos usar as funções @@IDENTITY, SCOPE_IDENTITY, e IDENT_CURRENT.

IDENT_CURRENT  - Retorna o último valor identidade gerado para uma tabela específica em qualquer sessão e em qualquer escopo.
@@IDENTITY -   Retorna o último valor identidade gerado para qualquer tabela na sessão atual, através de todos os escopos.(valor inserido na coluna com propriedade IDENTITY).
SCOPE_IDENTITY
- Retorna o último valor identidade gerado para qualquer tabela na sessão atual e no escopo atual.


Sendo que @@IDENTITY e SCOPE_IDENTITY retornam o último valor identidade gerado em qualquer tabela na sessão atual; porém  SCOPE_IDENTITY retorna o valor somente para o escopo atual.

Em nosso código iremos alterar a instrução SQL que inclui a imagem para :


const string SQL = "INSERT INTO [Imagens] ([nomeArquivo], [horaUpload], [MIME], [imagem])VALUES(@nomeArquivo, @horaUpload, @MIME, @imagem) SELECT SCOPE_IDENTITY()";
 

Vamos alterar o código que usa a instrução ExecuteNonQuery usando em seu lugar o ExecuteScalar e definindo a variável imagemID para obter o id da imagem salva:


int imagemID = Convert.ToInt16(cmd.ExecuteScalar());

hplnkExibeImagem.NavigateUrl = "~/ExibirImagem.aspx?ID=" + imagemID.ToString();
 

Vamos então incluir uma nova página web no projeto. No menu Web Site selecione Add New Item e selecione o template Web Form informando o nome ExibirImagem.aspx e clicando em Add. Agora já podermos usar a página ExibirImagem.aspx para exibir a imagem salva;

Onde temos a propriedade NavigateUrl do controle Hiperlink estamos usando a página ExibirImagem.aspx que incluímos no projeto e a referência ao id da imagem a ser recuperada e exibida na página.

O código completo ficou assim:

using (SqlConnection Conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))

{

try

{

const string SQL = "INSERT INTO [Imagens] ([nomeArquivo], [horaUpload], [MIME], [imagem])VALUES(@nomeArquivo, @horaUpload, @MIME, @imagem) SELECT SCOPE_IDENTITY()";
 

SqlCommand cmd = new SqlCommand(SQL, Conn);

cmd.Parameters.AddWithValue("@nomeArquivo", txtNomeArquivo.Text.Trim());

cmd.Parameters.AddWithValue("@MIME", fileType);

byte[] imageBytes = new byte[fupld.PostedFile.InputStream.Length + 1];

 

fupld.PostedFile.InputStream.Read(imageBytes, 0, imageBytes.Length);

cmd.Parameters.AddWithValue("@imagem", imageBytes);

cmd.Parameters.AddWithValue("@horaUpload", DateTime.Now);

 

lblmsg.Text = "<br />Arquivo enviado com sucesso <br />";

 

Conn.Open();

int imagemID = Convert.ToInt16(cmd.ExecuteScalar());

hplnkExibeImagem.NavigateUrl = "~/ExibirImagem.aspx?ID=" + imagemID.ToString();

Conn.Close();

 

}

catch

{

lblmsg.Text = " Erro ao enviar imagem ";

Conn.Close();

}

}

 

No evento Load da página ExibirImagem.aspx vamos incluir o seguinte código que irá recuperar a imagem a partir do id obtido na rotina acima e exibi-la:

protected void Page_Load(object sender, EventArgs e)

{

try

{

int imagemID = Convert.ToInt32(Request.QueryString["id"]);

 

//nomeArquivo], [horaUpload], [MIME], [imagem]

using (SqlConnection Conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))

{

const string SQL = "SELECT [MIME], [imagem] FROM [Imagens] WHERE [id] = @id";
 

SqlCommand myCommand = new SqlCommand(SQL, Conn);

myCommand.Parameters.AddWithValue("@id", imagemID);

Conn.Open();


SqlDataReader myReader = myCommand.ExecuteReader();


if
(myReader.Read())

{

    Response.ContentType = myReader["MIME"].ToString();

    Response.BinaryWrite((byte[])myReader["imagem"]);

}

   myReader.Close();

   Conn.Close();

}

}

catch (Exception ex)

{

Response.Write(ex.ToString());

}

}

Execute o web site e você verá a primeira página igual a mostrada no primeiro artigo, agora com o link - Clique aqui para Exibir a Imagem . A usar o link você verá a imagem recém incluída no seu banco de dados.

Dessa forma recuperamos a imagem que foi salva no banco de dados.

Pegue o projeto completo aqui : recuperaImagemBD.zip (sem a base de dados)(É o mesmo projeto que o artigo anterior com a recuperação)

Eu sei é apenas ASP .NET, mas eu gosto.

Referências:


José Carlos Macoratti