Trabalhando com arquivos em um site de Páginas da Web do ASP.NET (Razor)
por Tom FitzMacken
Este artigo explica como ler, gravar, acrescentar, excluir e carregar arquivos em um site de Páginas da Web do ASP.NET (Razor).
Observação
Se você quiser carregar imagens e manipulá-las (por exemplo, invertê-las ou redimensioná-las), consulte Trabalhando com imagens em um site Páginas da Web do ASP.NET.
O que você aprenderá:
- Como criar um arquivo de texto e gravar dados nele.
- Como acrescentar dados a um arquivo existente.
- Como ler um arquivo e exibi-lo.
- Como excluir arquivos de um site.
- Como permitir que os usuários carreguem um arquivo ou vários arquivos.
Estes são os ASP.NET recursos de programação introduzidos no artigo:
- O
File
objeto , que fornece uma maneira de gerenciar arquivos.- O
FileUpload
auxiliar.- O
Path
objeto , que fornece métodos que permitem manipular nomes de caminho e arquivo.Versões de software usadas no tutorial
- Páginas da Web do ASP.NET (Razor) 2
- WebMatrix 2
Este tutorial também funciona com o WebMatrix 3.
Criando um arquivo de texto e gravando dados nele
Além de usar um banco de dados em seu site, você pode trabalhar com arquivos. Por exemplo, você pode usar arquivos de texto como uma maneira simples de armazenar dados para o site. (Um arquivo de texto usado para armazenar dados às vezes é chamado de arquivo simples.) Os arquivos de texto podem estar em formatos diferentes, como .txt, .xmlou .csv (valores delimitados por vírgulas).
Se você quiser armazenar dados em um arquivo de texto, poderá usar o File.WriteAllText
método para especificar o arquivo a ser criado e os dados a serem gravados nele. Neste procedimento, você criará uma página que contém um formulário simples com três input
elementos (nome, sobrenome e endereço de email) e um botão Enviar . Quando o usuário enviar o formulário, você armazenará a entrada do usuário em um arquivo de texto.
Crie uma nova pasta chamada App_Data, se ela ainda não existir.
Na raiz do seu site, crie um novo arquivo chamado UserData.cshtml.
Substitua o conteúdo existente pelo seguinte:
@{ var result = ""; if (IsPost) { var firstName = Request["FirstName"]; var lastName = Request["LastName"]; var email = Request["Email"]; var userData = firstName + "," + lastName + "," + email + Environment.NewLine; var dataFile = Server.MapPath("~/App_Data/data.txt"); File.WriteAllText(@dataFile, userData); result = "Information saved."; } } <!DOCTYPE html> <html> <head> <title>Write Data to a File</title> </head> <body> <form id="form1" method="post"> <div> <table> <tr> <td>First Name:</td> <td><input id="FirstName" name="FirstName" type="text" /></td> </tr> <tr> <td>Last Name:</td> <td><input id="LastName" name="LastName" type="text" /></td> </tr> <tr> <td>Email:</td> <td><input id="Email" name="Email" type="text" /></td> </tr> <tr> <td></td> <td><input type="submit" value="Submit"/></td> </tr> </table> </div> <div> @if(result != ""){ <p>Result: @result</p> } </div> </form> </body> </html>
A marcação HTML cria o formulário com as três caixas de texto. No código, você usa a
IsPost
propriedade para determinar se a página foi enviada antes de iniciar o processamento.A primeira tarefa é obter a entrada do usuário e atribuí-la a variáveis. Em seguida, o código concatena os valores das variáveis separadas em uma cadeia de caracteres delimitada por vírgulas, que é armazenada em uma variável diferente. Observe que o separador de vírgula é uma cadeia de caracteres contida entre aspas (","), porque você está literalmente inserindo uma vírgula na cadeia de caracteres grande que está criando. No final dos dados que você concatena, adicione
Environment.NewLine
. Isso adiciona uma quebra de linha (um caractere de nova linha). O que você está criando com toda essa concatenação é uma cadeia de caracteres semelhante a esta:David,Jones,davidj@contoso.com
(Com uma quebra de linha invisível no final.)
Em seguida, você cria uma variável (
dataFile
) que contém o local e o nome do arquivo no qual armazenar os dados. Definir o local requer alguma manipulação especial. Em sites, é uma prática ruim fazer referência no código a caminhos absolutos, como C:\Folder\File.txt para arquivos no servidor Web. Se um site for movido, um caminho absoluto estará errado. Além disso, para um site hospedado (em vez de em seu próprio computador), você normalmente nem sabe qual é o caminho correto ao escrever o código.Mas, às vezes (como agora, para escrever um arquivo), você precisa de um caminho completo. A solução é usar o
MapPath
método doServer
objeto . Isso retorna o caminho completo para seu site. Para obter o caminho para a raiz do site, use o~
operador (para represen a raiz virtual do site) paraMapPath
. (Você também pode passar um nome de subpasta para ele, como ~/App_Data/, para obter o caminho dessa subpasta.) Em seguida, você pode concatenar informações adicionais sobre o que o método retorna para criar um caminho completo. Neste exemplo, você adiciona um nome de arquivo. (Você pode ler mais sobre como trabalhar com caminhos de arquivo e pasta em Introdução à programação de Páginas da Web do ASP.NET usando a sintaxe Razor.)O arquivo é salvo na pasta App_Data . Essa pasta é uma pasta especial em ASP.NET usada para armazenar arquivos de dados, conforme descrito em Introdução ao trabalho com um banco de dados em sites de Páginas da Web do ASP.NET.
O
WriteAllText
método doFile
objeto grava os dados no arquivo. Esse método usa dois parâmetros: o nome (com caminho) do arquivo para gravar e os dados reais a serem gravados. Observe que o nome do primeiro parâmetro tem um@
caractere como prefixo. Isso informa ASP.NET que você está fornecendo um literal de cadeia de caracteres textual e que caracteres como "/" não devem ser interpretados de maneiras especiais. (Para obter mais informações, consulte Introdução à programação da Web ASP.NET usando a sintaxe razor.)Observação
Para que seu código salve arquivos na pasta App_Data , o aplicativo precisa de permissões de leitura/gravação para essa pasta. No computador de desenvolvimento, isso normalmente não é um problema. No entanto, ao publicar seu site no servidor Web de um provedor de hospedagem, talvez seja necessário definir explicitamente essas permissões. Se você executar esse código no servidor de um provedor de hospedagem e receber erros, marcar com o provedor de hospedagem para descobrir como definir essas permissões.
Execute a página em um navegador.
Insira valores nos campos e clique em Enviar.
Feche o navegador.
Retorne ao projeto e atualize o modo de exibição.
Abra o arquivo data.txt . Os dados enviados no formulário estão no arquivo .
Feche o arquivo dedata.txt .
Anexando dados a um arquivo existente
No exemplo anterior, você usou WriteAllText
para criar um arquivo de texto que tem apenas um pedaço de dados nele. Se você chamar o método novamente e passar o mesmo nome de arquivo, o arquivo existente será completamente substituído. No entanto, depois de criar um arquivo, você geralmente deseja adicionar novos dados ao final do arquivo. Você pode fazer isso usando o AppendAllText
método do File
objeto .
No site, faça uma cópia do arquivo UserData.cshtml e nomeie a cópia UserDataMultiple.cshtml.
Substitua o bloco de código antes da marca de abertura
<!DOCTYPE html>
pelo seguinte bloco de código:@{ var result = ""; if (IsPost) { var firstName = Request["FirstName"]; var lastName = Request["LastName"]; var email = Request["Email"]; var userData = firstName + "," + lastName + "," + email + Environment.NewLine; var dataFile = Server.MapPath("~/App_Data/data.txt"); File.AppendAllText (@dataFile, userData); result = "Information saved."; } }
Esse código tem uma alteração no exemplo anterior. Em vez de usar
WriteAllText
, ele usa othe AppendAllText
método . Os métodos são semelhantes, exceto queAppendAllText
adicionam os dados ao final do arquivo. Assim como noWriteAllText
,AppendAllText
cria o arquivo se ele ainda não existir.Execute a página em um navegador.
Insira valores para os campos e clique em Enviar.
Adicione mais dados e envie o formulário novamente.
Retorne ao projeto, clique com o botão direito do mouse na pasta do projeto e clique em Atualizar.
Abra o arquivo data.txt . Agora ele contém os novos dados que você acabou de inserir.
Lendo e exibindo dados de um arquivo
Mesmo que você não precise gravar dados em um arquivo de texto, provavelmente às vezes precisará ler dados de um. Para fazer isso, você pode usar novamente o File
objeto . Você pode usar o File
objeto para ler cada linha individualmente (separada por quebras de linha) ou ler item individual, independentemente de como elas são separadas.
Este procedimento mostra como ler e exibir os dados que você criou no exemplo anterior.
Na raiz do seu site, crie um novo arquivo chamado DisplayData.cshtml.
Substitua o conteúdo existente pelo seguinte:
@{ var result = ""; Array userData = null; char[] delimiterChar = {','}; var dataFile = Server.MapPath("~/App_Data/data.txt"); if (File.Exists(dataFile)) { userData = File.ReadAllLines(dataFile); if (userData == null) { // Empty file. result = "The file is empty."; } } else { // File does not exist. result = "The file does not exist."; } } <!DOCTYPE html> <html> <head> <title>Reading Data from a File</title> </head> <body> <div> <h1>Reading Data from a File</h1> @result @if (result == "") { <ol> @foreach (string dataLine in userData) { <li> User <ul> @foreach (string dataItem in dataLine.Split(delimiterChar)) { <li>@dataItem</li > } </ul> </li> } </ol> } </div> </body> </html>
O código começa lendo o arquivo que você criou no exemplo anterior em uma variável chamada
userData
, usando essa chamada de método:File.ReadAllLines(dataFile)
O código para fazer isso está dentro de uma instrução
if
. Quando você deseja ler um arquivo, é uma boa ideia usar oFile.Exists
método para determinar primeiro se o arquivo está disponível. O código também verifica se o arquivo está vazio.O corpo da página contém dois
foreach
loops, um aninhado dentro do outro. O loop externoforeach
obtém uma linha de cada vez do arquivo de dados. Nesse caso, as linhas são definidas por quebras de linha no arquivo , ou seja, cada item de dados está em sua própria linha. O loop externo cria um novo item (<li>
elemento) dentro de uma lista ordenada (<ol>
elemento).O loop interno divide cada linha de dados em itens (campos) usando uma vírgula como delimitador. (Com base no exemplo anterior, isso significa que cada linha contém três campos : o nome, sobrenome e endereço de email, cada um separado por uma vírgula.) O loop interno também cria uma
<ul>
lista e exibe um item de lista para cada campo na linha de dados.O código ilustra como usar dois tipos de dados, uma matriz e o
char
tipo de dados. A matriz é necessária porque oFile.ReadAllLines
método retorna dados como uma matriz. Ochar
tipo de dados é necessário porque oSplit
método retorna umarray
no qual cada elemento é do tipochar
. (Para obter informações sobre matrizes, consulte Introdução à programação da Web ASP.NET usando a sintaxe razor.)Execute a página em um navegador. Os dados inseridos para os exemplos anteriores são exibidos.
Dica
Exibindo dados de um arquivo de Comma-Delimited do Microsoft Excel
Você pode usar o Microsoft Excel para salvar os dados contidos em uma planilha como um arquivo delimitado por vírgulas ( arquivo.csv ). Quando você faz isso, o arquivo é salvo em texto sem formatação, não no formato do Excel. Cada linha na planilha é separada por uma quebra de linha no arquivo de texto e cada item de dados é separado por uma vírgula. Você pode usar o código mostrado no exemplo anterior para ler um arquivo delimitado por vírgulas do Excel apenas alterando o nome do arquivo de dados em seu código.
Excluindo arquivos
Para excluir arquivos do seu site, você pode usar o File.Delete
método . Este procedimento mostra como permitir que os usuários excluam uma imagem (.jpg arquivo) de uma pasta de imagens se souberem o nome do arquivo.
Observação
Importante Em um site de produção, você normalmente restringe quem tem permissão para fazer alterações nos dados. Para obter informações sobre como configurar a associação e sobre maneiras de autorizar os usuários a executar tarefas no site, consulte Adicionando segurança e associação a um site de Páginas da Web do ASP.NET.
No site, crie uma subpasta chamada imagens.
Copie um ou mais arquivos .jpg na pasta de imagens .
Na raiz do site, crie um novo arquivo chamado FileDelete.cshtml.
Substitua o conteúdo existente pelo seguinte:
@{ bool deleteSuccess = false; var photoName = ""; if (IsPost) { photoName = Request["photoFileName"] + ".jpg"; var fullPath = Server.MapPath("~/images/" + photoName); if (File.Exists(fullPath)) { File.Delete(fullPath); deleteSuccess = true; } } } <!DOCTYPE html> <html> <head> <title>Delete a Photo</title> </head> <body> <h1>Delete a Photo from the Site</h1> <form name="deletePhoto" action="" method="post"> <p>File name of image to delete (without .jpg extension): <input name="photoFileName" type="text" value="" /> </p> <p><input type="submit" value="Submit" /></p> </form> @if(deleteSuccess) { <p> @photoName deleted! </p> } </body> </html>
Esta página contém um formulário em que os usuários podem inserir o nome de um arquivo de imagem. Eles não inserem a extensão de nome de arquivo .jpg ; restringindo o nome do arquivo assim, você ajuda a impedir que os usuários excluam arquivos arbitrários em seu site.
O código lê o nome do arquivo que o usuário inseriu e, em seguida, constrói um caminho completo. Para criar o caminho, o código usa o caminho do site atual (conforme retornado pelo
Server.MapPath
método), o nome da pasta de imagens , o nome que o usuário forneceu e ".jpg" como uma cadeia de caracteres literal.Para excluir o arquivo, o código chama o
File.Delete
método , passando-o o caminho completo que você acabou de construir. No final da marcação, o código exibe uma mensagem de confirmação de que o arquivo foi excluído.Execute a página em um navegador.
Insira o nome do arquivo a ser excluído e clique em Enviar. Se o arquivo tiver sido excluído, o nome do arquivo será exibido na parte inferior da página.
Permitir que os usuários carreguem um arquivo
O FileUpload
auxiliar permite que os usuários carreguem arquivos em seu site. O procedimento abaixo mostra como permitir que os usuários carreguem um único arquivo.
Adicione a biblioteca de auxiliares da Web ASP.NET ao seu site, conforme descrito em Instalando auxiliares em um site de Páginas da Web do ASP.NET, se você não a adicionou anteriormente.
Na pasta App_Data , crie uma nova pasta e nomeie-a como UploadedFiles.
Na raiz, crie um novo arquivo chamado FileUpload.cshtml.
Substitua o conteúdo existente na página pelo seguinte:
@using Microsoft.Web.Helpers; @{ var fileName = ""; if (IsPost) { var fileSavePath = ""; var uploadedFile = Request.Files[0]; fileName = Path.GetFileName(uploadedFile.FileName); fileSavePath = Server.MapPath("~/App_Data/UploadedFiles/" + fileName); uploadedFile.SaveAs(fileSavePath); } } <!DOCTYPE html> <html> <head> <title>FileUpload - Single-File Example</title> </head> <body> <h1>FileUpload - Single-File Example</h1> @FileUpload.GetHtml( initialNumberOfFiles:1, allowMoreFilesToBeAdded:false, includeFormTag:true, uploadText:"Upload") @if (IsPost) { <span>File uploaded!</span><br/> } </body> </html>
A parte do corpo da página usa o
FileUpload
auxiliar para criar a caixa de carregamento e os botões com os quais você provavelmente está familiarizado:As propriedades definidas para o
FileUpload
auxiliar especificam que você deseja que uma única caixa para o arquivo seja carregada e que você deseja que o botão enviar leia Carregar. (Você adicionará mais caixas posteriormente no artigo.)Quando o usuário clica em Carregar, o código na parte superior da página obtém o arquivo e o salva. O
Request
objeto que você normalmente usa para obter valores de campos de formulário também tem umaFiles
matriz que contém o arquivo (ou arquivos) que foram carregados. Você pode obter arquivos individuais de posições específicas na matriz , por exemplo, para obter o primeiro arquivo carregado, você obtémRequest.Files[0]
, para obter o segundo arquivo, você obtémRequest.Files[1]
e assim por diante. (Lembre-se de que, na programação, a contagem geralmente começa em zero.)Ao buscar um arquivo carregado, você o coloca em uma variável (aqui,
uploadedFile
) para poder manipulá-lo. Para determinar o nome do arquivo carregado, basta obter suaFileName
propriedade. No entanto, quando o usuário carrega um arquivo,FileName
contém o nome original do usuário, que inclui todo o caminho. Ele pode ter esta aparência:C:\Users\Public\Sample.txt
No entanto, você não quer todas essas informações de caminho, pois esse é o caminho no computador do usuário, não para o servidor. Você só deseja o nome do arquivo real (Sample.txt). Você pode remover apenas o arquivo de um caminho usando o
Path.GetFileName
método , desta forma:Path.GetFileName(uploadedFile.FileName)
O
Path
objeto é um utilitário que tem vários métodos como este que você pode usar para remover caminhos, combinar caminhos e assim por diante.Depois de obter o nome do arquivo carregado, você poderá criar um novo caminho para onde deseja armazenar o arquivo carregado em seu site. Nesse caso, você combina
Server.MapPath
, os nomes de pasta (App_Data/UploadedFiles) e o nome do arquivo recém-removido para criar um novo caminho. Em seguida, você pode chamar o método doSaveAs
arquivo carregado para realmente salvar o arquivo.Execute a página em um navegador.
Clique em Procurar e selecione um arquivo para carregar.
A caixa de texto ao lado do botão Procurar conterá o caminho e o local do arquivo.
Clique em Carregar.
No site, clique com o botão direito do mouse na pasta do projeto e clique em Atualizar.
Abra a pasta UploadedFiles . O arquivo que você carregou está na pasta .
Permitir que os usuários carreguem vários arquivos
No exemplo anterior, você permite que os usuários carreguem um arquivo. Mas você pode usar o FileUpload
auxiliar para carregar mais de um arquivo por vez. Isso é útil para cenários como carregar fotos, em que carregar um arquivo por vez é entediante. (Você pode ler sobre como carregar fotos em Trabalhando com imagens em um site de Páginas da Web do ASP.NET.) Este exemplo mostra como permitir que os usuários carreguem dois de cada vez, embora você possa usar a mesma técnica para carregar mais do que isso.
Adicione a biblioteca de auxiliares da Web ASP.NET ao seu site, conforme descrito em Instalando auxiliares em um site de Páginas da Web do ASP.NET, caso ainda não tenha feito isso.
Crie uma nova página chamada FileUploadMultiple.cshtml.
Substitua o conteúdo existente na página pelo seguinte:
@using Microsoft.Web.Helpers; @{ var message = ""; if (IsPost) { var fileName = ""; var fileSavePath = ""; int numFiles = Request.Files.Count; int uploadedCount = 0; for(int i =0; i < numFiles; i++) { var uploadedFile = Request.Files[i]; if (uploadedFile.ContentLength > 0) { fileName = Path.GetFileName(uploadedFile.FileName); fileSavePath = Server.MapPath("~/App_Data/UploadedFiles/" + fileName); uploadedFile.SaveAs(fileSavePath); uploadedCount++; } } message = "File upload complete. Total files uploaded: " + uploadedCount.ToString(); } } <!DOCTYPE html> <html> <head><title>FileUpload - Multiple File Example</title></head> <body> <form id="myForm" method="post" enctype="multipart/form-data" action=""> <div> <h1>File Upload - Multiple-File Example</h1> @if (!IsPost) { @FileUpload.GetHtml( initialNumberOfFiles:2, allowMoreFilesToBeAdded:true, includeFormTag:true, addText:"Add another file", uploadText:"Upload") } <span>@message</span> </div> </form> </body> </html>
Neste exemplo, o
FileUpload
auxiliar no corpo da página é configurado para permitir que os usuários carreguem dois arquivos por padrão. ComoallowMoreFilesToBeAdded
está definido comotrue
, o auxiliar renderiza um link que permite que o usuário adicione mais caixas de upload:Para processar os arquivos que o usuário carrega, o código usa a mesma técnica básica que você usou no exemplo anterior : obtenha um arquivo de
Request.Files
e salve-o. (Incluindo as várias coisas que você precisa fazer para obter o nome de arquivo e o caminho corretos.) A inovação desta vez é que o usuário pode estar carregando vários arquivos e você não sabe muitos. Para descobrir, você pode obterRequest.Files.Count
.Com esse número em mãos, você pode percorrer
Request.Files
, buscar cada arquivo e salvá-lo. Quando você quiser executar um loop conhecido várias vezes por meio de uma coleção, poderá usar umfor
loop, desta forma:for(int i =0; i < numFiles; i++) { var uploadedFile = Request.Files[i]; if (uploadedFile.ContentLength > 0) { fileName = Path.GetFileName(uploadedFile.FileName); // etc. }
A variável
i
é apenas um contador temporário que passará de zero para qualquer limite superior definido. Nesse caso, o limite superior é o número de arquivos. Mas como o contador começa em zero, como é comum para contar cenários em ASP.NET, o limite superior é, na verdade, um a menos que a contagem de arquivos. (Se três arquivos forem carregados, a contagem será zero a 2.)A
uploadedCount
variável totaliza todos os arquivos carregados e salvos com êxito. Esse código explica a possibilidade de um arquivo esperado não ser capaz de ser carregado.Execute a página em um navegador. O navegador exibe a página e suas duas caixas de carregamento.
Selecione dois arquivos para carregar.
Clique em Adicionar outro arquivo. A página exibe uma nova caixa de carregamento.
Clique em Carregar.
No site, clique com o botão direito do mouse na pasta do projeto e clique em Atualizar.
Abra a pasta UploadedFiles para ver os arquivos carregados com êxito.
Recursos adicionais
Trabalhando com imagens em um site de Páginas da Web do ASP.NET