ASP.NET 2.0 - Download de arquivos


Você  quer permitir ao usuário poder efetuar o download de um determinado arquivo do seu servidor web  e não sabe como implementar esta funcionalidade em ASP.NET 2.0 ?

Este artigo vai mostrar como é fácil permitir que o usuário selecione um arquivo de uma lista e efetue o download do arquivo a partir do seu servidor web.

Você só vai precisar do Visual Web Developer 2005 Express Edition para acompanhar este artigo. Vamos lá...

Nosso exemplo terá duas etapas:

  1. A apresentação dos arquivos ao usuário a partir de um diretório no servidor
  2. A seleção e o download do arquivo pelo usuário

1- Inicie o VWD e crie um novo web site a partir do menu File opção New web site... e informe o nome arquivosDownload;

2- Clique com o botão direito sobre o nome do projeto e selecione a opção New Folder;

3- A seguir informe o nome imagens para o novo diretório criado no projeto;

4- Clique sobre o diretório criado e selecione a opção Add Existing Item e selecione alguns arquivos para incluir no diretório;

2- Selecione a página Default.aspx e no modo Design inclua os seguintes componentes:

Disponha o leiaute da página Default.aspx conforme a figura abaixo:

No nosso exemplo estou usando um controle ListBox para obter os arquivos do diretório imagens e apresentar ao usuário na página Default.aspx. Os arquivos deverão ser apresentados quando da carga da página e por isto o código que realiza esta tarefa será colocado no evento Load da página e tem o seguinte código:

Nota: O namespace usado no projeto é: Imports System.IO. Inclua as seguinte linhas de código no inicio da página:

Option Explicit On
Option
Strict On
Imports
System.IO

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

        Dim arquivos() As String
        Dim index As Integer

        If (Not Page.IsPostBack) Then
            'Obtem a lista de arquivos no diretório imagens
            arquivos= Directory.GetFiles(Server.MapPath("imagens"))

            'removemos o caminho dos arquivos a serem exibidos
            For index = 0 To arquivos.Length - 1
                arquivos(index) = New FileInfo(arquivos(index)).Name
            Next index
            'vincula a lista dos arquivos no array arquivos ao controle no formulário listbox
            lstArquivos.DataSource = arquivos
            lstArquivos.DataBind()
            'seleciona a primeira entrada da lista
            lstArquivos.SelectedIndex = 0
        End If

End Sub 

Para realizar esta tarefa irei usar o método GetFiles da classe Directory de forma a obter o nome dos arquivos no diretório
pré-definido e retorná-los em um array(arquivos()). Este método retorna o nome completo para cada arquivo encontrado no diretório e não é bem isto que queremos. Por isso irei remover em seguida o caminho de cada arquivo para apresentar somente o nome do mesmo ao usuário. A seguir o array retornado é vinculado ao controle de servidor ListBox para que sejam exibidos na página.

Quando o usuário selecionar o arquivo e clicar no botão para efetuar o download o evento ServerClick será disparado e nele temos o código abaixo que irá obter o nome do arquivo selecionado e irá efetuar o download do mesmo:

 Protected Sub btnDownload_ServerClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnDownload.ServerClick

        Dim arquivo As FileInfo
        Dim nomeArquivo As String

        'Obtêm o nome compleo do arquivo selecionado
        nomeArquivo = Server.MapPath("imagens") & "\" & lstArquivos.SelectedItem.Text

        'Obtêm os dados do arquivo pois o tamanho é requerido para efetuar o download
        arquivo = New FileInfo(nomeArquivo)
        'envia para o browser
        Response.Clear()
        Response.AddHeader("Content-Disposition", "attachment; filename=" & lstArquivos.SelectedItem.Text)
        Response.AddHeader("Content-Length", arquivo.Length.ToString())
        Response.ContentType = "application/octet-stream"
        Response.WriteFile(nomeArquivo)
        Response.End()
    End Sub

 

As propriedades o objeto Response usadas no código são:

Clear limpa qualquer buffer de saída HTML
AddHeader Inclui um novo cabeçalho HTTP e um valor ao Response HTTP
ContentType Define o tipo de conteúdo HTTP para o objeto Response.(Define o tipo MIME)
WriteFile Envia o conteúdo de um arquivo texto , XML , HTML para o Navegador com um stream
End Encerra o tratamento da requisição do cliente.

Nota: O tipo MIME permite que o seu navegador saiba que tipo de arquivo esta tratando. O tipo MIME Octet-stream usado refere-se a arquivos binários, se fosse um arquivo .doc o tipo MIME seria application/msword.

Lembre-se que que qualquer código que aparecer depois de Response.End() não será executado pois o comando envia todos os dados do buffer presentes no objeto Response para o cliente e para a execução da página e dispara o evento Application.EndRequest.

Ao executar o projeto no servidor web do VWD iremos obter o seguinte resultado:

Poderíamos ter adotado a estratégia de passar o nome do arquivo para download em uma página HTML como um parâmetro para uma página aspx. Desta forma teríamos em uma página HTML um link para o arquivo da seguinte forma:

<a href="download.aspx?arquivo=/imagens/macoratti.gif">Efetuar o download do arquivo imagem</a>

 A página download.aspx teria o seguinte código:

<%@ Page language="vb" runat="server" explicit="true" strict="true" %>

<script language="vb" runat="server">


Sub Page_Load(Sender As Object, E As EventArgs)


Dim strRequisicao As String = Request.QueryString("arquivo")


             'se algo foi passado como parâmetro

If strRequisicao <> "" Then   
  
'Obtem o caminho absoluto do arquivo
   Dim path As String = Server.MapPath(strRequest)
   'obtem o objeto Arquivo como FileInfo

   Dim Arquivo As System.IO.FileInfo = New System.IO.FileInfo(path)
   'Se o arquivo existir no servidor

   If Arquivo.Exists Then
     'define os cabeçalhos apropriados

     Response.Clear()

      Response.AddHeader("Content-Disposition", "attachment; filename=" & Arquivo.Name)

      Response.AddHeader("Content-Length", Arquivo.Length.ToString())

      Response.ContentType = "application/octet-stream"

      Response.WriteFile(Arquivo.FullName)

     Response.End   

   Else

     Response.Write("O arquivo não existe.")

   End If

Else

   Response.Write("Informe um arquivo para download.")

End If

End Sub

</script>

Pegue o código completo do projeto aqui: arquivosDownload.zip

Bom estudo e até o próximo artigo ASP...


José Carlos Macoratti