Compartilhar via


Carregar arquivos (C#)

por Scott Mitchell

Baixar PDF

Saiba como permitir que os usuários carreguem arquivos binários (como documentos do Word ou PDF) para o seu site, onde podem ser armazenados no sistema de arquivos do servidor ou no banco de dados.

Introdução

Todos os tutoriais que examinamos até agora funcionaram exclusivamente com dados de texto. No entanto, muitos aplicativos têm modelos de dados que capturam texto e dados binários. Um site de namoro online pode permitir que os usuários carreguem uma foto para associar ao seu perfil. Um site de recrutamento pode permitir que os usuários carreguem seu currículo como um documento do Microsoft Word ou PDF.

Trabalhar com dados binários adiciona um novo conjunto de desafios. Devemos decidir como os dados binários são armazenados no aplicativo. A interface usada para inserir novos registros deve ser atualizada para permitir que o usuário carregue um arquivo de seu computador e etapas extras devem ser executadas para exibir ou fornecer um meio de baixar os dados binários associados a um registro. Neste tutorial e nos próximos três, exploraremos como superar esses desafios. No final desses tutoriais, teremos construído um aplicativo totalmente funcional que associa uma imagem e um folheto em PDF a cada categoria. Neste tutorial específico, examinaremos diferentes técnicas para armazenar dados binários e exploraremos como permitir que os usuários carreguem um arquivo de seu computador e o salvem no sistema de arquivos do servidor Web.

Observação

Os dados binários que fazem parte do modelo de dados de um aplicativo às vezes são chamados de BLOB, um acrônimo para Binary Large OBject. Nestes tutoriais optei por usar a terminologia dados binários, embora o termo BLOB seja sinônimo.

Etapa 1: Criando o trabalho com páginas da Web de dados binários

Antes de começarmos a explorar os desafios associados à adição de suporte para dados binários, vamos primeiro reservar um momento para criar as páginas ASP.NET em nosso projeto de site que precisaremos para este tutorial e os próximos três. Comece adicionando uma nova pasta chamada BinaryData. Em seguida, adicione as seguintes páginas ASP.NET a essa pasta, certificando-se de associar cada página à Site.master página mestra:

  • Default.aspx
  • FileUpload.aspx
  • DisplayOrDownloadData.aspx
  • UploadInDetailsView.aspx
  • UpdatingAndDeleting.aspx

Adicione as páginas ASP.NET para os tutoriais relacionados a dados binários

Figura 1: Adicionar as páginas ASP.NET para os tutoriais relacionados a dados binários

Como nas outras pastas, Default.aspx na BinaryData pasta listará os tutoriais em sua seção. Lembre-se de que o SectionLevelTutorialListing.ascx Controle de Usuário fornece essa funcionalidade. Portanto, adicione esse Controle de Usuário arrastando-o Default.aspx do Gerenciador de Soluções para o modo de exibição Design da página.

Adicione o controle de usuário SectionLevelTutorialListing.ascx a Default.aspx

Figura 2: Adicionar o controle de usuário a Default.aspx (clique para exibir a SectionLevelTutorialListing.ascx imagem em tamanho real)

Por fim, adicione essas páginas como entradas ao Web.sitemap arquivo. Especificamente, adicione a seguinte marcação após o Aprimorando o GridView <siteMapNode>:

<siteMapNode 
    title="Working with Binary Data" 
    url="~/BinaryData/Default.aspx" 
    description="Extend the data model to include collecting binary data.">
    
    <siteMapNode 
        title="Uploading Files" 
        url="~/BinaryData/FileUpload.aspx" 
        description="Examine the different ways to store binary data on the 
                     web server and see how to accept uploaded files from users 
                     with the FileUpload control." />
    <siteMapNode 
        title="Display or Download Binary Data" 
        url="~/BinaryData/DisplayOrDownloadData.aspx" 
        description="Let users view or download the captured binary data." />
    <siteMapNode 
        title="Adding New Binary Data" 
        url="~/BinaryData/UploadInDetailsView.aspx" 
        description="Learn how to augment the inserting interface to 
                     include a FileUpload control." />
    <siteMapNode 
        title="Updating and Deleting Existing Binary Data" 
        url="~/BinaryData/UpdatingAndDeleting.aspx" 
        description="Learn how to update and delete existing binary data." />
</siteMapNode>

Após a atualização Web.sitemap, reserve um momento para visualizar o site de tutoriais por meio de um navegador. O menu à esquerda agora inclui itens para os tutoriais Trabalhando com dados binários.

O mapa do site agora inclui entradas para os tutoriais Trabalhando com dados binários

Figura 3: O mapa do site agora inclui entradas para os tutoriais Trabalhando com dados binários

Etapa 2: Decidindo onde armazenar os dados binários

Os dados binários associados ao modelo de dados do aplicativo podem ser armazenados em um dos dois locais: no sistema de arquivos do servidor Web com uma referência ao arquivo armazenado no banco de dados; ou diretamente no próprio banco de dados (consulte a Figura 4). Cada abordagem tem seu próprio conjunto de prós e contras e merece uma discussão mais detalhada.

Os dados binários podem ser armazenados no sistema de arquivos ou diretamente no banco de dados

Figura 4: Os dados binários podem ser armazenados no sistema de arquivos ou diretamente no banco de dados (clique para exibir a imagem em tamanho real)

Imagine que quiséssemos estender o banco de dados Northwind para associar uma imagem a cada produto. Uma opção seria armazenar esses arquivos de imagem no sistema de arquivos do servidor Web e registrar o Products caminho na tabela. Com essa abordagem, adicionaríamos uma ImagePath coluna à Products tabela do tipo varchar(200), talvez. Quando um usuário carrega uma imagem para Chai, essa imagem pode ser armazenada no sistema de arquivos do servidor Web em ~/Images/Tea.jpg, onde ~ representa o caminho físico do aplicativo. Ou seja, se o site estiver enraizado no caminho C:\Websites\Northwind\físico , ~/Images/Tea.jpg seria equivalente a C:\Websites\Northwind\Images\Tea.jpg. Depois de fazer o upload do arquivo de imagem, atualizamos o registro Chai na Products tabela para que sua ImagePath coluna faça referência ao caminho da nova imagem. Poderíamos usar ~/Images/Tea.jpg ou apenas Tea.jpg se decidíssemos que todas as imagens do produto seriam colocadas na pasta do Images aplicativo.

As principais vantagens de armazenar os dados binários no sistema de arquivos são:

  • Facilidade de implementação Como veremos em breve, armazenar e recuperar dados binários armazenados diretamente no banco de dados envolve um pouco mais de código do que ao trabalhar com dados por meio do sistema de arquivos. Além disso, para que um usuário visualize ou baixe dados binários, ele deve receber uma URL para esses dados. Se os dados residirem no sistema de arquivos do servidor Web, a URL será direta. Se os dados estiverem armazenados no banco de dados, no entanto, será necessário criar uma página da Web que recupere e retorne os dados do banco de dados.
  • Acesso mais amplo aos dados binários Os dados binários podem precisar estar acessíveis a outros serviços ou aplicativos, aqueles que não podem extrair os dados do banco de dados. Por exemplo, as imagens associadas a cada produto também podem precisar estar disponíveis para os usuários por meio de FTP, caso em que queremos armazenar os dados binários no sistema de arquivos.
  • Desempenho se os dados binários forem armazenados no sistema de arquivos, a demanda e o congestionamento de rede entre o servidor de banco de dados e o servidor Web serão menores do que se os dados binários forem armazenados diretamente no banco de dados.

A principal desvantagem de armazenar dados binários no sistema de arquivos é que ele desacopla os dados do banco de dados. Se um registro for excluído da Products tabela, o arquivo associado no sistema de arquivos do servidor Web não será excluído automaticamente. Devemos escrever código extra para excluir o arquivo ou o sistema de arquivos ficará cheio de arquivos órfãos e não utilizados. Além disso, ao fazer backup do banco de dados, devemos nos certificar de fazer backups dos dados binários associados no sistema de arquivos também. Mover o banco de dados para outro site ou servidor apresenta desafios semelhantes.

Como alternativa, os dados binários podem ser armazenados diretamente em um banco de dados do Microsoft SQL Server 2005 criando uma coluna do tipo varbinary. Assim como acontece com outros tipos de dados de comprimento variável, você pode especificar um comprimento máximo dos dados binários que podem ser mantidos nessa coluna. Por exemplo, para reservar no máximo 5.000 bytes, use varbinary(5000); varbinary(MAX) permite o tamanho máximo de armazenamento, cerca de 2 GB.

A principal vantagem de armazenar dados binários diretamente no banco de dados é o forte acoplamento entre os dados binários e o registro do banco de dados. Isso simplifica muito as tarefas de administração do banco de dados, como backups ou mover o banco de dados para um site ou servidor diferente. Além disso, a exclusão de um registro exclui automaticamente os dados binários correspondentes. Há também benefícios mais sutis de armazenar os dados binários no banco de dados. Consulte Armazenando arquivos binários diretamente no banco de dados usando o ASP.NET 2.0 para uma discussão mais aprofundada.

Observação

No Microsoft SQL Server 2000 e versões anteriores, o varbinary tipo de dados tinha um limite máximo de 8.000 bytes. Para armazenar até 2 GB de dados binários, o image tipo de dados precisa ser usado. Com a adição de no SQL Server 2005, no entanto, o image tipo de MAX dados foi preterido. Ele ainda tem suporte para compatibilidade com versões anteriores, mas a Microsoft anunciou que o image tipo de dados será removido em uma versão futura do SQL Server.

Se você estiver trabalhando com um modelo de dados mais antigo, poderá ver o image tipo de dados. A tabela do banco de dados Northwind tem uma Picture coluna que pode ser usada para armazenar os dados binários Categories de um arquivo de imagem para a categoria. Como o banco de dados Northwind tem suas raízes no Microsoft Access e em versões anteriores do SQL Server, essa coluna é do tipo image.

Para este tutorial e os próximos três, usaremos as duas abordagens. A Categories tabela já possui uma Picture coluna para armazenar o conteúdo binário de uma imagem para a categoria. Adicionaremos uma coluna adicional, BrochurePath, para armazenar um caminho para um PDF no sistema de arquivos do servidor Web que pode ser usado para fornecer uma visão geral polida e com qualidade de impressão da categoria.

Etapa 3: Adicionando aBrochurePathcoluna àCategoriestabela

Atualmente, a tabela Categorias tem apenas quatro colunas: CategoryID, CategoryName, Description, e Picture. Além desses campos, precisamos adicionar um novo que aponte para o folheto da categoria (se houver). Para adicionar essa coluna, vá para o Gerenciador de Servidores, faça uma busca detalhada nas Tabelas, clique com o botão direito do mouse na tabela e escolha Abrir Definição de Tabela (consulte a Categories Figura 5). Se você não vir o Gerenciador de Servidores, abra-o selecionando a opção Gerenciador de Servidores no menu Exibir ou pressione Ctrl+Alt+S.

Adicione uma nova varchar(200) coluna à Categories tabela que é chamada BrochurePath e permite NULL s e clique no ícone Salvar (ou pressione Ctrl+S).

Adicionar uma coluna BrochurePath à tabela de categorias

Figura 5: Adicionar uma BrochurePath coluna à tabela (clique para exibir a Categories imagem em tamanho real)

Etapa 4: Atualizando a arquitetura para usar asPicturecolunas eBrochurePath

A CategoriesDataTable na Camada de Acesso a Dados (DAL) atualmente tem quatro DataColumn s definidos: CategoryID, CategoryName, Descriptione NumberOfProducts. Quando projetamos originalmente esta DataTable no tutorial Criando uma Camada de Acesso a Dados , a CategoriesDataTable única tinha as três primeiras colunas; a NumberOfProducts coluna foi adicionada no tutorial Mestre/Detalhes Usando uma Lista com Marcadores de Registros Mestre com uma Lista de Dados de Detalhes.

Conforme discutido em Criando uma Camada de Acesso a Dados, as DataTables no Conjunto de Dados Tipado compõem os objetos de negócios. Os TableAdapters são responsáveis por se comunicar com o banco de dados e preencher os objetos de negócios com os resultados da consulta. O CategoriesDataTable é preenchido CategoriesTableAdapterpelo , que tem três métodos de recuperação de dados:

  • GetCategories() executa a consulta principal do TableAdapter e retorna os CategoryIDcampos , CategoryNamee Description de todos os registros na Categories tabela. A consulta principal é o que é usado pelos métodos e Update gerados Insert automaticamente.
  • GetCategoryByCategoryID(categoryID)retorna os CategoryIDcampos , CategoryNamee Description da categoria cujo CategoryID é igual a categoryID.
  • GetCategoriesAndNumberOfProducts() - retorna os CategoryIDcampos , CategoryNamee Description para todos os registros na Categories tabela. Também usa uma subconsulta para retornar o número de produtos associados a cada categoria.

Observe que nenhuma dessas consultas retorna a Categories tabela s Picture ou BrochurePath colunas; nem CategoriesDataTable fornece DataColumn s para esses campos. Para trabalhar com a imagem e BrochurePath as propriedades, precisamos primeiro adicioná-las ao CategoriesDataTable e, em seguida, atualizar a CategoriesTableAdapter classe para retornar essas colunas.

Adicionando oPictureeBrochurePath``DataColumn s

Comece adicionando essas duas colunas ao CategoriesDataTable. Clique com o botão direito do CategoriesDataTable mouse no cabeçalho s, selecione Adicionar no menu de contexto e escolha a opção Coluna. Isso criará um novo DataColumn na DataTable chamado Column1. Renomeie esta coluna para Picture. Na janela Propriedades, defina a DataColumn propriedade s DataType como System.Byte[] (essa não é uma opção na lista suspensa; você precisa digitá-la).

Criar uma DataColumn chamada Picture cujo DataType é System.Byte[]

Figura 6: Criar um DataColumn nome Picture cujo DataType é System.Byte[] (clique para exibir a imagem em tamanho real)

Adicione outro DataColumn ao DataTable, nomeando-o BrochurePath usando o valor padrão DataType (System.String).

Retornando osPicturevalores eBrochurePathdo TableAdapter

Com esses dois DataColumn s adicionados ao , estamos prontos para atualizar o CategoriesDataTableCategoriesTableAdapter. Poderíamos ter esses dois valores de coluna retornados na consulta principal do TableAdapter, mas isso traria de volta os dados binários toda vez que o GetCategories() método fosse invocado. Em vez disso, vamos atualizar a consulta principal TableAdapter para trazer de volta BrochurePath e criar um método de recuperação de dados adicional que retorna uma coluna s Picture de categoria específica.

Para atualizar a consulta principal do TableAdapter, clique com o botão direito do CategoriesTableAdapter mouse no cabeçalho s e escolha a opção Configurar no menu de contexto. Isso abre o Assistente de Configuração do Adaptador de Tabela, que vimos em vários tutoriais anteriores. Atualize a consulta para trazer de volta o BrochurePath e clique em Concluir.

Atualize a lista de colunas na instrução SELECT para retornar também BrochurePath

Figura 7: Atualizar a lista de colunas na SELECT instrução para retornar BrochurePath também (clique para exibir a imagem em tamanho real)

Ao usar instruções SQL ad hoc para o TableAdapter, atualizar a lista de colunas na consulta principal atualiza a lista de colunas para todos os SELECT métodos de consulta no TableAdapter. Isso significa que o GetCategoryByCategoryID(categoryID) método foi atualizado para retornar a BrochurePath coluna, que pode ser o que pretendíamos. No entanto, também atualizou a lista de colunas no GetCategoriesAndNumberOfProducts() método, removendo a subconsulta que retorna o número de produtos para cada categoria! Portanto, precisamos atualizar a consulta desse SELECT método. Clique com o botão direito do GetCategoriesAndNumberOfProducts() mouse no método, escolha Configurar e reverta a SELECT consulta de volta ao seu valor original:

SELECT CategoryID, CategoryName, Description, 
       (SELECT COUNT(*) 
            FROM Products p 
            WHERE p.CategoryID = c.CategoryID) 
       as NumberOfProducts
FROM Categories c

Em seguida, crie um novo método TableAdapter que retorna um valor de coluna de Picture categoria específica. Clique com o botão direito do CategoriesTableAdapter mouse no cabeçalho s e escolha a opção Adicionar Consulta para iniciar o Assistente de Configuração de Consulta TableAdapter. A primeira etapa deste assistente nos pergunta se queremos consultar dados usando uma instrução SQL ad-hoc, um novo procedimento armazenado ou um existente. Selecione Usar instruções SQL e clique em Avançar. Como retornaremos uma linha, escolha a opção SELECT que retorna linhas da segunda etapa.

Selecione a opção Usar instruções SQL

Figura 8: Selecione a opção Usar instruções SQL (clique para exibir a imagem em tamanho real)

Como a consulta retornará um registro da tabela de categorias, escolha SELECT que retorna linhas

Figura 9: Como a consulta retornará um registro da tabela Categorias, escolha SELECT que retorna linhas (clique para exibir a imagem em tamanho real)

Na terceira etapa, insira a seguinte consulta SQL e clique em Avançar:

SELECT     CategoryID, CategoryName, Description, BrochurePath, Picture
FROM       Categories
WHERE      CategoryID = @CategoryID

A última etapa é escolher o nome do novo método. Use FillCategoryWithBinaryDataByCategoryID e GetCategoryWithBinaryDataByCategoryID para os padrões Preencher uma DataTable e Retornar uma DataTable, respectivamente. Clique em Concluir para concluir o assistente.

Escolha os nomes para os métodos do TableAdapter

Figura 10: Escolher os nomes para os métodos do TableAdapter (clique para exibir a imagem em tamanho completo)

Observação

Depois de concluir o Assistente de Configuração de Consulta do Adaptador de Tabela, você poderá ver uma caixa de diálogo informando que o novo texto de comando retorna dados com esquema diferente do esquema da consulta principal. Em resumo, o assistente está observando que a consulta GetCategories() principal do TableAdapter retorna um esquema diferente daquele que acabamos de criar. Mas é isso que queremos, então você pode desconsiderar esta mensagem.

Além disso, lembre-se de que, se você estiver usando instruções SQL ad hoc e usar o assistente para alterar a consulta principal do TableAdapter em algum momento posterior, ele modificará a GetCategoryWithBinaryDataByCategoryID lista de colunas da instrução do SELECT método para incluir apenas as colunas da consulta principal (ou seja, removerá a Picture coluna da consulta). Você terá que atualizar manualmente a lista de colunas para retornar a Picture coluna, semelhante ao que fizemos com o GetCategoriesAndNumberOfProducts() método anteriormente nesta etapa.

Depois de adicionar os dois DataColumn s ao CategoriesDataTable e o GetCategoryWithBinaryDataByCategoryID método ao CategoriesTableAdapter, essas classes no Typed DataSet Designer devem se parecer com a captura de tela na Figura 11.

O DataSet Designer inclui as novas colunas e o método

Figura 11: O designer de conjunto de dados inclui as novas colunas e o método

Atualizando a BLL (Camada de Lógica de Negócios)

Com a DAL atualizada, tudo o que resta é aumentar a BLL (Business Logic Layer) para incluir um método para o novo CategoriesTableAdapter método. Adicione o seguinte método à classe CategoriesBLL:

[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Select, false)] 
public Northwind.CategoriesDataTable 
    GetCategoryWithBinaryDataByCategoryID(int categoryID)
{
    return Adapter.GetCategoryWithBinaryDataByCategoryID(categoryID);
}

Etapa 5: Carregando um arquivo do cliente para o servidor Web

Ao coletar dados binários, muitas vezes esses dados são fornecidos por um usuário final. Para capturar essas informações, o usuário precisa ser capaz de fazer upload de um arquivo de seu computador para o servidor web. Os dados carregados precisam ser integrados ao modelo de dados, o que pode significar salvar o arquivo no sistema de arquivos do servidor Web e adicionar um caminho ao arquivo no banco de dados ou gravar o conteúdo binário diretamente no banco de dados. Nesta etapa, veremos como permitir que um usuário carregue arquivos de seu computador para o servidor. No próximo tutorial, voltaremos nossa atenção para a integração do arquivo carregado com o modelo de dados.

ASP.NET 2.0 s novo controle da Web FileUpload fornece um mecanismo para os usuários enviarem um arquivo de seu computador para o servidor Web. O controle FileUpload é renderizado como um <input> elemento cujo type atributo é definido como file, que os navegadores exibem como uma caixa de texto com um botão Procurar. Clicar no botão Procurar abre uma caixa de diálogo na qual o usuário pode selecionar um arquivo. Quando o formulário é postado, o conteúdo do arquivo selecionado é enviado junto com o postback. No lado do servidor, as informações sobre o arquivo carregado podem ser acessadas por meio das propriedades do controle FileUpload.

Para demonstrar o carregamento de arquivos, abra a FileUpload.aspx página na BinaryData pasta, arraste um controle FileUpload da Caixa de Ferramentas para o Designer e defina a propriedade do ID controle como UploadTest. Em seguida, adicione um controle Web de botão definindo suas ID propriedades e Text e UploadButton Carregar Arquivo Selecionado, respectivamente. Por fim, coloque um controle Web Label abaixo do Button, limpe sua Text propriedade e defina sua ID propriedade como UploadDetails.

Adicionar um controle FileUpload à página ASP.NET

Figura 12: Adicionar um controle FileUpload à página ASP.NET (clique para exibir a imagem em tamanho real)

A Figura 13 mostra essa página quando visualizada por meio de um navegador. Observe que clicar no botão Procurar abre uma caixa de diálogo de seleção de arquivo, permitindo que o usuário escolha um arquivo de seu computador. Depois que um arquivo é selecionado, clicar no botão Carregar Arquivo Selecionado causa um postback que envia o conteúdo binário do arquivo selecionado para o servidor Web.

O usuário pode selecionar um arquivo para carregar de seu computador para o servidor

Figura 13: O usuário pode selecionar um arquivo para carregar de seu computador para o servidor (clique para exibir a imagem em tamanho real)

No postback, o arquivo carregado pode ser salvo no sistema de arquivos ou seus dados binários podem ser trabalhados diretamente por meio de um Stream. Para este exemplo, vamos criar uma ~/Brochures pasta e salvar o arquivo carregado lá. Comece adicionando a Brochures pasta ao site como uma subpasta do diretório raiz. Em seguida, crie um manipulador de eventos para o UploadButton evento s Click e adicione o seguinte código:

protected void UploadButton_Click(object sender, EventArgs e)
{
    if (UploadTest.HasFile == false)
    {
        // No file uploaded!
        UploadDetails.Text = "Please first select a file to upload...";            
    }
    else
    {
        // Display the uploaded file's details
        UploadDetails.Text = string.Format(
                @"Uploaded file: {0}<br />
                  File size (in bytes): {1:N0}<br />
                  Content-type: {2}", 
                  UploadTest.FileName, 
                  UploadTest.FileBytes.Length,
                  UploadTest.PostedFile.ContentType);
        // Save the file
        string filePath = 
            Server.MapPath("~/Brochures/" + UploadTest.FileName);
        UploadTest.SaveAs(filePath);
    }
}

O controle FileUpload fornece uma variedade de propriedades para trabalhar com os dados carregados. Por exemplo, a HasFile propriedade indica se um arquivo foi carregado pelo usuário, enquanto a FileBytes propriedade fornece acesso aos dados binários carregados como uma matriz de bytes. O Click manipulador de eventos começa garantindo que um arquivo tenha sido carregado. Se um arquivo tiver sido carregado, o Rótulo mostrará o nome do arquivo carregado, seu tamanho em bytes e seu tipo de conteúdo.

Observação

Para garantir que o usuário carregue um arquivo, você pode verificar a HasFile propriedade e exibir um aviso se for false, ou você pode usar o controle RequiredFieldValidator em vez disso.

O FileUpload salva SaveAs(filePath) o arquivo carregado no filePath especificado. filePath deve ser um caminho físico (C:\Websites\Brochures\SomeFile.pdf) em vez de um caminho virtual (/Brochures/SomeFile.pdf). O Server.MapPath(virtPath) método usa um caminho virtual e retorna seu caminho físico correspondente. Aqui, o caminho virtual é ~/Brochures/fileName, onde fileName é o nome do arquivo carregado. Consulte o método Server.MapPath para obter mais informações sobre caminhos virtuais e físicos e como usar Server.MapPatho .

Depois de concluir o manipulador de Click eventos, reserve um momento para testar a página em um navegador. Clique no botão Procurar e selecione um arquivo do disco rígido e, em seguida, clique no botão Carregar arquivo selecionado. O postback enviará o conteúdo do arquivo selecionado para o servidor Web, que exibirá informações sobre o arquivo antes de salvá-lo na ~/Brochures pasta. Depois de carregar o arquivo, retorne ao Visual Studio e clique no botão Atualizar no Gerenciador de Soluções. Você deve ver o arquivo que acabou de enviar na pasta ~/Brochuras!

O arquivo EvolutionValley.jpg foi carregado no servidor web

Figura 14: O arquivo EvolutionValley.jpg foi carregado no servidor Web (clique para exibir a imagem em tamanho real)

EvolutionValley.jpg foi salvo na pasta ~/Brochuras

Figura 15: EvolutionValley.jpg foi salvo na ~/Brochures pasta

Sutilezas ao salvar arquivos carregados no sistema de arquivos

Há várias sutilezas que devem ser abordadas ao salvar o upload de arquivos no sistema de arquivos do servidor Web. Primeiro, há a questão da segurança. Para salvar um arquivo no sistema de arquivos, o contexto de segurança no qual a página ASP.NET está sendo executada deve ter permissões de gravação. O servidor Web de desenvolvimento do ASP.NET é executado no contexto de sua conta de usuário atual. Se você estiver usando o IIS (Serviços de Informações da Internet) da Microsoft como servidor Web, o contexto de segurança dependerá da versão do IIS e de sua configuração.

Outro desafio de salvar arquivos no sistema de arquivos gira em torno de nomear os arquivos. Atualmente, nossa página salva todos os arquivos carregados no ~/Brochures diretório usando o mesmo nome do arquivo no computador do cliente. Se o usuário A carregar um folheto com o nome Brochure.pdf, o arquivo será salvo como ~/Brochure/Brochure.pdf. Mas e se algum tempo depois o usuário B carregar um arquivo de brochura diferente que tenha o mesmo nome de arquivo (Brochure.pdf)? Com o código que temos agora, o arquivo do usuário A será substituído pelo upload do usuário B.

Existem várias técnicas para resolver conflitos de nome de arquivo. Uma opção é proibir o upload de um arquivo se já existir um com o mesmo nome. Com essa abordagem, quando o usuário B tenta carregar um arquivo chamado Brochure.pdf, o sistema não salva o arquivo e, em vez disso, exibe uma mensagem informando ao usuário B para renomear o arquivo e tentar novamente. Outra abordagem é salvar o arquivo usando um nome de arquivo exclusivo, que pode ser um GUID (identificador global exclusivo) ou o valor das colunas de chave primária do registro de banco de dados correspondente (supondo que o upload esteja associado a uma linha específica no modelo de dados). No próximo tutorial, exploraremos essas opções com mais detalhes.

Desafios envolvidos com quantidades muito grandes de dados binários

Esses tutoriais pressupõem que os dados binários capturados são modestos em tamanho. Trabalhar com quantidades muito grandes de arquivos de dados binários com vários megabytes ou mais apresenta novos desafios que estão além do escopo desses tutoriais. Por exemplo, por padrão, ASP.NET rejeitará uploads de mais de 4 MB, embora isso possa ser configurado por meio do <httpRuntime> elemento em Web.config. O IIS também impõe suas próprias limitações de tamanho de upload de arquivo. Além disso, o tempo necessário para carregar arquivos grandes pode exceder os 110 segundos padrão ASP.NET aguardará uma solicitação. Também há problemas de memória e desempenho que surgem ao trabalhar com arquivos grandes.

O controle FileUpload é impraticável para uploads de arquivos grandes. À medida que o conteúdo do arquivo está sendo postado no servidor, o usuário final deve aguardar pacientemente sem qualquer confirmação de que o upload está progredindo. Isso não é tanto um problema ao lidar com arquivos menores que podem ser carregados em alguns segundos, mas pode ser um problema ao lidar com arquivos maiores que podem levar minutos para serem carregados. Há uma variedade de controles de upload de arquivos de terceiros que são mais adequados para lidar com uploads grandes e muitos desses fornecedores fornecem indicadores de progresso e gerenciadores de upload ActiveX que apresentam uma experiência de usuário muito mais refinada.

Se seu aplicativo precisar lidar com arquivos grandes, você precisará investigar cuidadosamente os desafios e encontrar soluções adequadas para suas necessidades específicas.

Resumo

A criação de um aplicativo que precisa capturar dados binários apresenta vários desafios. Neste tutorial, exploramos os dois primeiros: decidir onde armazenar os dados binários e permitir que um usuário carregue conteúdo binário por meio de uma página da web. Nos próximos três tutoriais, veremos como associar os dados carregados a um registro no banco de dados, bem como exibir os dados binários ao lado de seus campos de dados de texto.

Boa programação!

Leitura Adicional

Para obter mais informações sobre os tópicos discutidos neste tutorial, consulte os seguintes recursos:

Sobre o autor

Scott Mitchell, autor de sete livros ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Web da Microsoft desde 1998. Scott trabalha como consultor, instrutor e escritor independente. Seu último livro é Sams Teach Yourself ASP.NET 2.0 em 24 horas. Ele pode ser contatado em mitchell@4GuysFromRolla.com. ou através de seu blog, que pode ser encontrado em http://ScottOnWriting.NET.

Agradecimentos especiais a

Esta série de tutoriais foi revisada por muitos revisores úteis. Os principais revisores deste tutorial foram Teresa Murphy e Bernadette Leigh. Interessado em revisar meus próximos artigos do MSDN? Em caso afirmativo, envie-me uma mensagem para mitchell@4GuysFromRolla.com.