Patrocínio Natura

Gerenciador de Arquivos com Ajax e ASP.Net

10 de outubro de 2007

Olá pessoal! Primeiramente gostaria de agradecer o grande retorno por parte dos leitores de meu último artigo, que tem enviado sugestões e até implementado mais o código. É realmente gratificante saber que meus textos estão ajudando.

Hoje irei abordar algo menos comum, mas que considero bem interessante. Iremos começar a desenvolver um Gerenciador de Arquivos em ASP.net utilizando o Magic Ajax. Este é um artigo um pouco mais avançado, e destina-se à quem tenha um mínimo conhecimento em .Net e Orientação a Objetos.

Para quem ainda não conhece o MagicAjax, ele é um framework open-source quem visa facilitar a implementação de AJAX nas aplicações ASP.net. Em junho eu escrevi um artigo aqui no iMasters falando sobre ele. Clique aqui para ler este artigo.

. Antes de mais nada, visite o link e veja o exemplo on-line:
. Ou baixe o código fonte do artigo:

Iremos utilizar um controle DataList para exibir os dados na página. Isso irá facilitar muito nossa vida.
Então vamos começar.

01. Adicionando o MagicAjax

Faça o download do MagicAjax e copie a dll para a pasta Bin do novo site. Em seguida, crie um arquivo Web.Config (ou altere o atual) com as seguintes tags:











Isto é necessário para utilizar o MagicAjax em nossas páginas.

02. Classes do gerenciador de arquivos

Para facilitar as coisas, nossa aplicação será Orientado à Objetos.

Criaremos uma classe chamada Arquivo que irá conter os dados de cada arquivo ou pasta que será mostrada.

Iremos também criar uma classe chamada Gerenciador que será responsável por obter uma lista com os arquivos e subdiretórios de uma determinada pasta. Estas duas classes estarão no arquivo Arquivo.vb.

02.1. A Classe Arquivo

Crie um arquivo chamado Arquivo.vb e adicione o código abaixo. Essa classe contém 7 propriedades essenciais que serão utilizadas no decorrer do artigo. Apesar do nome da classe ser “Arquivo”, ela recebe tanto arquivos quanto diretórios. Para diferenciar, temos a propriedade Tipo.

Essa classe também tem uma função que diz qual será o ícone do arquivo. Coloquei os arquivos mais básicos. Você provavelmente vai querer adicionar ícones para outros tipos de arquivos, e verá que é bem fácil.

Public Class Arquivo 
Private _Nome As String
Private _Caminho As String
Private _Tamanho As String
Private _Icone As String
Private _DataCriacao As Date
Private _DataAlteracao As Date
Private _Tipo As TipoArquivo
'Nome do arquivo. Ex.: imagem.jpg
Public Property Nome() As String
Get
Return _Nome
End Get
Set(ByVal value As String)
_Nome = value
End Set
End Property
'Caminho completo do arquivo. Ex.: c:\inetpub\walteram\imagem.jpg
Public Property Caminho() As String
Get
Return _Caminho
End Get
Set(ByVal value As String)
_Caminho = value
End Set
End Property
'Tamanho do arquivo em kBytes
Public Property Tamanho() As String
Get
Return _Tamanho
End Get
Set(ByVal value As String)
If IsNumeric(value) Then
'Aqui convertemos para KB.
'Você poderia dar um tratamento mais detalhado para mostrar MB, KB, GB, etc,
'de acordo com cada situação.
_Tamanho = Math.Ceiling(CInt(value) / 1024).ToString & " KB"
Else
_Tamanho = value
End If
End Set
End Property
'Ícone do arquivo
Public Property Icone() As String
Get
Return _Icone
End Get
Set(ByVal value As String)
_Icone = AcharIcone(value)
End Set
End Property
'Data da criação do arquivo
Public Property DataCriacao() As Date
Get
Return _DataCriacao
End Get
Set(ByVal value As Date)
_DataCriacao = value
End Set
End Property
'Data da última alteração do arquivo
Public Property DataAlteracao() As Date
Get
Return _DataAlteracao
End Get
Set(ByVal value As Date)
_DataAlteracao = value
End Set
End Property
'Tipo. Pode ser pasta ou arquivo
Public Property Tipo() As TipoArquivo
Get
Return _Tipo
End Get
Set(ByVal value As TipoArquivo)
_Tipo = value
End Set
End Property
'Retorna o caminho do ícone de acordo com a extensão
Private Shared Function AcharIcone(ByVal Extensao As String) As String
Select Case Extensao
Case ".gif", ".peg", ".jpe", ".jpg", ".png"
Return "images/IconesArquivos/imagem.gif"
Case ".txt"
Return "images/IconesArquivos/texto.gif"
Case ".htm", ".xml", ".xsl", ".css", ".html", ".config"
Return "images/IconesArquivos/html.gif"
Case ".mp3", ".wav", ".wma", ".au", ".mid", ".ram", ".rm", ".snd", ".asf"
Return "images/IconesArquivos/audio.gif"
Case ".zip", "tar", ".gz", ".rar", ".cab", ".tgz"
Return "images/IconesArquivos/zip.gif"
Case ".asp", ".wsh", ".js", ".vbs", ".aspx", ".cs", ".vb"
Return "images/IconesArquivos/script.gif"
Case "pasta"
Return "images/IconesArquivos/pasta.gif"
Case Else
Return "images/IconesArquivos/generico.gif"
End Select
End Function
Public Enum TipoArquivo
Arquivo
Diretorio
End Enum
End Class

02.2. A Classe Gerenciador

No mesmo arquivo, adicione o código abaixo. Esta é a classe Gerenciador. Esta classe tem dois métodos compartilhados.

A função Obter recebe o nome de uma pasta e retorna uma lista de seus arquivos e subpastas. Note que essa lista não é um simples Array. Trata-se de uma Lista do tipo arquivo, uma Collection (coleção).
Coleções são parecidos com arrays. A diferença é que as coleções possui funcionalidades muito úteis, e são ótimas para trabalhar com dados complexos. Uma coleção pode ser uma Lista (List), uma Pilha (Stack), uma Fila (Queue), etc. Neste caso, utilizamos uma Lista.

Quando a função Obter é chamada, criamos uma nova lista de subdiretórios e arquivos de uma determinada pasta. Utilizamos o namespace System.IO do .Net, que fornece operações no sistema de arquivos.

A classe também possui um procedimento chamado Ordenar. Esse método recebe uma lista de arquivos e ordena por uma determinada propriedade. Assim, podemos ordenar a lista de arquivos por Nome do arquivo, Tamanho, Data de Criação, etc.

Public Class Gerenciador
Public Shared Function Obter(ByVal Pasta As String, ByVal Ordem As String) As _ Collections.Generic.List(Of Arquivo)
'Aqui iremos criar uma Collection, baseada na classe Arquivo
Obter = New Collections.Generic.List(Of Arquivo)
'Busca todos os diretórios
Dim Item As Arquivo
For Each strPasta As String In IO.Directory.GetDirectories(Pasta)
Dim _Pasta As New IO.DirectoryInfo(strPasta)
Item = New Arquivo
Item.Caminho = _Pasta.FullName.Replace(Pasta, "")
Item.Nome = _Pasta.Name
Item.Tamanho = "-"
Item.Icone = "pasta"
Item.DataCriacao = _Pasta.CreationTime
Item.DataAlteracao = _Pasta.LastWriteTime
Item.Tipo = Arquivo.TipoArquivo.Diretorio
Obter.Add(Item)
Next
If Ordem <> "Nome" Then Ordenar(Obter, Ordem, 0)
'Busca todos os arquivos
Dim QuantPastas As Integer = Obter.Count
For Each strArquivo As String In IO.Directory.GetFiles(Pasta)
Dim _Arq As New IO.FileInfo(strArquivo)
Item = New Arquivo
Item.Caminho = _Arq.FullName.Replace(Pasta, "")
Item.Nome = _Arq.Name
Item.Tamanho = _Arq.Length.ToString
Item.Icone = _Arq.Extension
Item.DataCriacao = _Arq.CreationTime
Item.DataAlteracao = _Arq.LastWriteTime
Item.Tipo = Arquivo.TipoArquivo.Arquivo
Obter.Add(Item)
Next
If Ordem <> "Nome" Then Ordenar(Obter, Ordem, QuantPastas)
Return Obter 
End Function
'Permite ordenar uma lista de arquivos por alguma propriedade
Private Shared Sub Ordenar(ByRef Lista As Generic.List(Of Arquivo), ByVal Coluna _ 
As String, ByVal Inicio As Integer)
Dim menor As Integer, aux As Arquivo
For i As Integer = Inicio To Lista.Count - 2
menor = i
For j As Integer = i + 1 To Lista.Count - 1
If CallByName(Lista(j), Coluna, CallType.Get) < _
CallByName(Lista(menor), Coluna, CallType.Get) Then
menor = j
End If
Next
If menor <> i Then
aux = Lista(i)
Lista(i) = Lista(menor)
Lista(menor) = aux
End If
Next
End Sub
End Class

Agora a base de nossa aplicação está pronta. O próximo passo é criar a página que irá consumir estas classes.

03. Exibindo os dados

Crie um arquivo chamado Default.aspx e adicione a marcação abaixo.


Gerenciador de Arquivos

<%#DirectCast(Container.DataItem, Arquivo).Tamanho%> <%#DirectCast(Container.DataItem, Arquivo).DataCriacao%> <%#DirectCast(Container.DataItem, Arquivo).DataAlteracao%> <%#DirectCast(Container.DataItem, Arquivo).Tamanho%> <%#DirectCast(Container.DataItem, Arquivo).DataCriacao%> <%#DirectCast(Container.DataItem, Arquivo).DataAlteracao%>

A primeira vista, você deve ter um susto com tanto código, e tão embolado. Mas é bem simples.
Na página, temos um AjaxPanel, e dentro dele um DataList. Simples. Tudo que estiver dentro do AjaxPanel (que é um web control do MagicAjax) irá agir de forma assíncrona.

O código acima está sem estilos. No download você encontrará a página já formatada.

Cada linha do Datalist irá ter dois campos ocultos, com o nome do ítem (nome.txt) e seu tipo (arquivo|pasta).

O Datalist tem 3 seções que você deve dar atenção:

01. Header (Cabeçalho): É onde estão os links de ordenação e um botão para subir um nível nas pastas. Ele tem também um checkbox para selecionar todos.

02. EditItemTemplate: Esta seção é mostrada quando clicamos para renomear algum arquivo ou pasta.

03. ItemTemplate: Esta é a seção mais importante do datalist. É onde irão aparecer os arquivos e pastas.

A função DirectCast tem o mesmo efeito da função CType, mas faz uma conversão direta para a classe Arquivo, sendo por isso muito mais rápida.

04. Populando o Datalist

Iremos agora fazer a ligação dos dados com o datalist. Para isso, adicione o código abaixo no topo da página Default.aspx. Pra facilitar sua vida o código está bastante comentado.

<%@ Page Language="VB" ResponseEncoding="ISO-8859-1" culture="pt-BR"%>
<%@ Assembly Src="Arquivo.vb" %>
<%@ Import Namespace="Arquivo" %>
<%@ Register Assembly="MagicAjax" Namespace="MagicAjax.UI.Controls" TagPrefix="ajax" %>

A função mais importante desse código todo é a função Bind que faz a ligação dos dados com o DataList.

Ligamos o DataList à função Obter, explicada anteriormente. Ou seja, ligamos ele a uma Lista do tipo Arquivo. Novidade?

Você já deve estar acostumado a ligar um datalist à um DataSet, ou a um DataReader. Na verdade, o Datalist, assim como o Datagrid ou o Repeater, permite ser ligado à praticamente qualquer coisa.
Para os programadores de ASP convencional, isso tudo deve estar parecendo loucura. Poucas linguagem para Web oferecem essa flexibilidade, e uma quantidade tão grande e tão controles. Aliás, tudo nesse artigo é novo em .Net!

No código acima também já está o código para abrir, renomear e excluir itens, e para ordenar o Datalist. Por isso é tão grande.

Quando você clica para renomear um ítem, a linha tranforma-se numa EditItemTemplate, onde você poderá alterar o nome do arquivo ou pasta.

Quando você clica para abrir uma pasta, ou subir um nível, a função Bind é chamada novamente para aquela pasta. Quando você clica no linka para abrir um arquivo, é redirecionado para a página Download.aspx, que força o download do arquivo.

05. Forçando o Download de arquivos

Para finalizar, crie uma página chamada Download.aspx e adicione o código abaixo. Esta página será responsável por forçar o download de um arquivo:

<%@ Page language="VB" %>

No próximo artigo, você verá como apagar mais de um arquivo, mover, copiar, criar pastas e fazer upload. Enquanto isso, não deixe de implementar esse aí.

Bem pessoal, é isso.

O Código parece complicado, mas é bem simples. Não hesite em mandar e-mail para mim se tiver alguma dúvida. Infelizmente nem sempre dá responder na mesma hora, ou no mesmo dia, mas prometo ajudar. Continuem colaborando, enviando críticas, dúvidas e sugestões.

Um abraço.

 

 

Walter Amorim
Visite o site do colunista: http://www.walteram.com.br

Compatilhe esse artigo!

Nenhum Comentário

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

This site uses Akismet to reduce spam. Learn how your comment data is processed.