ASP.NET -  Trabalhando com BLOBs no SQL Server IV


Continuando o meu artigo ASP .NET - Trabalhando com dados binários no SQL Server ,  nesta última parte mostrarei o código usado para gerenciar as fotos, incluindo, deletando incluindo fotos no banco de dados.

A interface que criamos esta exibida abaixo, ela é muito simples, pode ser melhorada, mas vamos usá-la e mostrar como podemos realizar o gerenciamento dos dados referente as fotos sendo armazenadas como dados binários no SQL Server;

Iremos definir o código usando o modo code-behind no arquivo Default.aspx.vb tratando os eventos da página e do controle DetailsView.

ASP.NET oferece suporte a dois métodos para escrever código : Codigo in-line  e Code-behind

Se você ainda não conhece o CodeBehind permite separar o código da linguagem do código HTML de forma que ao ser compilado o code-behind é encapsulado em uma DLL e dessa forma somente é necessário o envio do arquivo ASPX para o servidor.

Quando criamos um novo formulário web dois arquivos são criados : um com a extensão .aspx e outro com o mesmo nome e a extensão .aspx.vb para VB.NET ou .aspx.cs para C#.

Abra o arquivo Default.aspx.vb e no início do mesmo declare o namespace :  Imports System.IO

1-) Evento Load da página:

No evento Load da página vamos forçar a exibição do controle usando o modo de inserção de dados se não houver nenhuma foto gravada na tabela.

Estou verificando a propriedade IsPostBack da página, esta propriedade da página indica se o POST que está chegando para processamento tem origem de uma submição (Submit) do usuário ou se é a primeira requisição da página.

Se for um Submit  é porque o usuário realizou uma ação, como um clique num botão. Neste caso seu valor é True caso contrário o valor será False.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

 

If Not IsPostBack Then

     BindData()

     If DetailsView1.Rows.Count = 0 Then

          DetailsView1.ChangeMode(DetailsViewMode.Insert)

     End If

End If
 

End Sub

Nesta caso chamamos o método BindData()  que é mostrado em seguida e que chama o método getFotos da classe FotoHelper atribuindo o valor retornado ao controle DetailsView;

Se não houver dados então forçamos a propriedade ChangeMode do DetailsView como Insert:  DetailsView1.ChangeMode(DetailsViewMode.Insert)

2-) O método BindData()

Private Sub BindData()
 

Dim photos As List(Of Foto) = FotoHelper.getFotos()


DetailsView1.DataSource = photos

DetailsView1.DataBind()


End
Sub

 

3-) Usando o evento DetailsView1_ItemDeleting

Para excluir um registro da tabela iremos usar o evento  ItemDeleting do DetailsView. Este evento é disparado antes que um comando Delete for executado na fonte de dados.

Então quando o usuário clicar no botão Deleta este evento será disparado.  Veja o código que colocamos neste evento:

Protected Sub DetailsView1_ItemDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewDeleteEventArgs) Handles DetailsView1.ItemDeleting

 

Dim fotoid As Integer = Convert.ToInt32(DetailsView1.DataKey(0))


FotoHelper.Deletar(fotoid)

BindData()


End
Sub

 

No código estamos obtendo o código da foto(fotoid) e em seguida chamando o método Deletar passando o código como parâmetro. Lembre-se que o método Deletar usa a seguinte instrução SQL :

cmd.CommandText = "DELETE FROM fotos where fotoid=@fotoid"

Dessa forma excluímos uma determinada foto da tabela.

4-) Usando o evento DetailsView1_ItemInserting

O evento ItemInserting é disparado antes que um comando Insert for executado na fonte de dados.

Dessa forma incluímos o seguinte código neste evento:

Protected Sub DetailsView1_ItemInserting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewInsertEventArgs) Handles DetailsView1.ItemInserting

 

Dim p As New Foto()

Dim t1 As TextBox = DirectCast(DetailsView1.Rows(0).Cells(1).Controls(0), TextBox)

Dim t2 As TextBox = DirectCast(DetailsView1.Rows(1).Cells(1).Controls(1), TextBox)
 

Dim fu As FileUpload = DirectCast(DetailsView1.Rows(2).Cells(1).Controls(1), FileUpload)

 

p.Titulo = t1.Text

p.Descricao = t2.Text

Dim imgdatastream As Stream = fu.PostedFile.InputStream

Dim imgdatalen As Integer = fu.PostedFile.ContentLength

Dim imgdata As Byte() = New Byte(imgdatalen - 1) {}

Dim n As Integer = imgdatastream.Read(imgdata, 0, imgdatalen)

 

p.FotoDados = imgdata

FotoHelper.Inserir(p)

 

BindData()

 

End Sub

Note que neste código precisamos obter os valores das caixas de textos (TextBox) e do controle FileUpload e após efetuarmos o tratamento do arquivo recebido usamos o método Inserir da classe FotoHelper.

5-) Usando o evento DetailsView1_ItemUpdating

O evento ItemUpdating é disparado antes que um comando Update for executado na fonte de dados.

Neste evento inserimos o seguinte código:

Protected Sub DetailsView1_ItemUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewUpdateEventArgs) Handles DetailsView1.ItemUpdating

 

Dim p As New Foto()

 

Dim t1 As TextBox = DirectCast(DetailsView1.Rows(0).Cells(1).Controls(0), TextBox)

Dim t2 As TextBox = DirectCast(DetailsView1.Rows(1).Cells(1).Controls(1), TextBox)

Dim fu As FileUpload = DirectCast(DetailsView1.Rows(2).Cells(1).Controls(1), FileUpload)

 

p.FotoID = Convert.ToInt32(DetailsView1.DataKey(0))

 

p.Titulo = t1.Text

p.Descricao = t2.Text

 

Dim imgdatastream As Stream = fu.PostedFile.InputStream

Dim imgdatalen As Integer = fu.PostedFile.ContentLength

Dim imgdata As Byte() = New Byte(imgdatalen - 1) {}

 

Dim n As Integer = imgdatastream.Read(imgdata, 0, imgdatalen)

 

p.FotoDados = imgdata

 

FotoHelper.Atualizar(p)

 

BindData()

 

End Sub

Aqui além de obter os valores dos controles TextBox e do controle FileUpload temos que obter o código da foto pois desejamos atualizar os dados apenas da foto atual.

O método Atualizar(p) é usado e recebe como parâmetro o objeto Foto com os dados da foto atual.

6-) Usando o evento DetailsView1_ModeChanging

O evento ModeChanging é disparado antes que a propriedade mode do DetailsView seja alterada;

Protected Sub DetailsView1_ModeChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewModeEventArgs) Handles DetailsView1.ModeChanging

 

DetailsView1.ChangeMode(e.NewMode)

BindData()

End Sub

 

A cada vez que houver uma mudança no modo do DetailsView obtemos o novo modo e chamamos o método BindData() para exibir os dados.

7-) Usando o evento DetailsView1_PageIndexChanging

O evento PageIndexChanging é disparado quando o índice do DetailsView é alterado;

Protected Sub DetailsView1_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewPageEventArgs) Handles DetailsView1.PageIndexChanging


DetailsView1.PageIndex = e.NewPageIndex
BindData()

End Sub

A cada vez que houver uma mudança no índice do DetailsView obtemos o novo índice e chamamos o método BindData().

Dessa forma implementamos todas as funcionalidades necessárias ao gerenciamento do nosso Álbum de Fotos, na verdade é uma aplicação bem simples, mas pode servir de base para soluções mais robustas.

Para encerrar uma visão da aplicação em execução:

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

Pegue o projeto completo aqui: AlbumFotos.zip (sem a base de dados)

referências:


José Carlos Macoratti