 ASP.NET 
-  Trabalhando com BLOBs no SQL Server IV
   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 IfEnd 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.DataBind() 
     
 | 
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:
| ProtectedSub 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)) 
     BindData() 
     
 | 
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:
| ProtectedSub 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:
| ProtectedSub 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;
| ProtectedSub 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;
| ProtectedSub DetailsView1_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewPageEventArgs) Handles DetailsView1.PageIndexChanging 
 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)
 
AlbumFotos.zip (sem a base de dados)
referências:
José Carlos Macoratti