Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье объясняется, как читать, записывать, добавлять, удалять и отправлять файлы на сайте ASP.NET веб-страниц (Razor).
Замечание
Если вы хотите отправить изображения и управлять ими (например, перевернуть или изменить их размер), см. статью "Работа с изображениями" на сайте веб-страниц ASP.NET.
Что вы узнаете:
- Создание текстового файла и запись данных в него.
- Добавление данных в существующий файл.
- Как считывать файл и отображать его.
- Удаление файлов с веб-сайта.
- Как разрешить пользователям отправлять один файл или несколько файлов.
Это возможности программирования ASP.NET, представленные в статье:
- Объект
File, который предоставляет способ управления файлами.- Помощник
FileUpload.- Объект
Path, предоставляющий методы, позволяющие управлять именами путей и файлов.Версии программного обеспечения, используемые в руководстве
- Веб-страницы ASP.NET (Razor) 2
- WebMatrix 2
Это руководство также работает с WebMatrix 3.
Создание текстового файла и запись данных в него
Помимо использования базы данных на веб-сайте, вы можете работать с файлами. Например, текстовые файлы можно использовать как простой способ хранения данных для сайта. (Текстовый файл, используемый для хранения данных, иногда называется неструктурированным файлом.) Текстовые файлы могут быть в разных форматах, таких как.txt, .xmlили .csv (значения с разделителями-запятыми).
Если вы хотите хранить данные в текстовом файле, можно использовать File.WriteAllText метод, чтобы указать файл для создания и записи данных в него. В этой процедуре вы создадите страницу, содержащую простую форму с тремя input элементами (имя, фамилия и адрес электронной почты) и кнопкой "Отправить ". Когда пользователь отправляет форму, вы сохраните входные данные пользователя в текстовом файле.
Создайте новую папку с именем App_Data, если она еще не существует.
В корне веб-сайта создайте файл с именем UserData.cshtml.
Замените существующее содержимое следующим образом:
@{ 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>Разметка HTML создает форму с тремя текстовыми полями. В коде вы используете свойство
IsPostдля определения того, была ли отправлена страница перед началом обработки.Первая задача — получить входные данные пользователя и назначить его переменным. Затем код объединяет значения отдельных переменных в одну строку с разделителями-запятыми, которая затем хранится в другой переменной. Обратите внимание, что разделитель запятых является строкой, содержащейся в кавычках (","), так как вы буквально внедряете запятую в большую строку, которую вы создаете. В конце сцепляемых данных добавьте
Environment.NewLine. При этом добавляется разрыв строки (символ новой строки). То, что вы создаете со всем этим объединением, — это строка, которая выглядит следующим образом:David,Jones,davidj@contoso.com(С невидимым разрывом строки в конце.)
Затем вы создадите переменную (
dataFile), содержащую расположение и имя файла для хранения данных. Для задания местоположения требуется специальная обработка. На веб-сайтах это плохая практика ссылаться на код на абсолютные пути, такие как C:\Folder\File.txt для файлов на веб-сервере. Если веб-сайт будет перемещён, абсолютный путь станет неправильным. Кроме того, для сайта на хостинге (в отличие от собственного компьютера) вы обычно даже не знаете, какой путь является правильным при написании кода.Но иногда (например, для написания файла) вам нужен полный путь. Решением является использование
MapPathметодаServerобъекта. Эта функция возвращает полный путь к вашему веб-сайту. Чтобы получить путь к корню веб-сайта, вы используете~оператор (чтобы представить виртуальный корень сайта) вMapPath. (Вы также можете передать в него имя вложенной папки, например ~/App_Data/, чтобы получить путь к этой вложенной папке.) Затем можно объединить дополнительные сведения о том, что возвращает метод, чтобы создать полный путь. В этом примере вы добавите имя файла. (Дополнительные сведения о работе с путями к файлам и папкам см. в ASP.NET статье "Введение в программирование веб-страниц с помощью синтаксиса Razor".)Файл сохраняется в папке App_Data . Эта папка является специальной папкой в ASP.NET, которая используется для хранения файлов данных, как описано в разделе "Введение в работу с базой данных" на сайтах веб-страниц ASP.NET.
Метод
WriteAllTextFileобъекта записывает данные в файл. Этот метод принимает два параметра: имя (с путем) файла для записи, а также фактические данные для записи. Обратите внимание, что имя первого параметра имеет@символ в качестве префикса. Это указывает ASP.NET, что вы предоставляете дословный строковый литерал, и что символы, такие как "/", не должны интерпретироваться каким-либо специальным образом. (Дополнительные сведения см. в статье "Введение в ASP.NET веб-программирование с помощью синтаксиса Razor".)Замечание
Чтобы код сохранял файлы в папке App_Data , приложению требуются разрешения на чтение и запись для этой папки. На компьютере разработки это обычно не проблема. Однако при публикации сайта на веб-сервере поставщика услуг размещения может потребоваться явно задать эти разрешения. Если вы запускаете этот код на сервере поставщика услуг размещения и получаете ошибки, обратитесь к поставщику услуг размещения, чтобы узнать, как задать эти разрешения.
Запустите страницу в браузере.
Введите значения в поля и нажмите кнопку "Отправить".
Закройте браузер.
Вернитесь в проект и обновите представление.
Откройте файлdata.txt . Данные, отправленные в форме, отображаются в файле.
Закройте файл data.txt .
Добавление данных в существующий файл
В предыдущем примере вы использовали WriteAllText для создания текстового файла, который имеет только один фрагмент данных в нем. При повторном вызове метода и передаче того же имени файла существующий файл полностью перезаписан. Однако после создания файла часто требуется добавить новые данные в конец файла. Это можно сделать с помощью AppendAllText метода File объекта.
На веб-сайте создайте копию файла UserData.cshtml и назовите файл userDataMultiple.cshtml.
Замените блок кода перед открывающим
<!DOCTYPE html>тегом следующим блоком кода:@{ 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."; } }Этот код имеет одно изменение в нем из предыдущего примера. Вместо использования
WriteAllTextон используетthe AppendAllTextметод. Методы аналогичны, за исключением того, чтоAppendAllTextданные добавляются в конец файла. Как и в случае сWriteAllText,AppendAllTextсоздает файл, если он еще не существует.Запустите страницу в браузере.
Введите значения полей и нажмите кнопку "Отправить".
Добавьте дополнительные данные и снова отправьте форму.
Вернитесь к проекту, щелкните правой кнопкой мыши папку проекта и нажмите кнопку "Обновить".
Откройте файлdata.txt . Теперь он содержит новые данные, которые вы только что ввели.
Чтение и отображение данных из файла
Даже если вам не нужно записывать данные в текстовый файл, иногда потребуется считывать данные из одного. Для этого можно снова использовать File объект. Объект можно использовать для чтения каждой File строки по отдельности (разделенных разрывами строк) или для чтения отдельных элементов независимо от того, как они разделены.
В этой процедуре показано, как считывать и отображать данные, созданные в предыдущем примере.
В корне веб-сайта создайте файл с именем DisplayData.cshtml.
Замените существующее содержимое следующим образом:
@{ 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>Код начинается с чтения файла, созданного в предыдущем примере, в переменную с именем
userData, используя этот вызов метода:File.ReadAllLines(dataFile)Код для этого находится внутри инструкции
if. При чтении файла рекомендуется использоватьFile.Existsметод, чтобы определить, доступен ли файл. Код также проверяет, является ли файл пустым.Тело страницы содержит два
foreachцикла, один вложенный внутри другого. Внешнийforeachцикл получает одну строку за раз из файла данных. В этом случае строки определяются разрывами строк в файле, то есть каждый элемент данных находится в собственной строке. Внешний цикл создает новый элемент (<li>) внутри упорядоченного списка (<ol>).Внутренний цикл разделяет каждую строку данных на элементы (поля) с помощью запятой в качестве разделителя. (На основе предыдущего примера это означает, что каждая строка содержит три поля — имя, фамилию и адрес электронной почты, каждый из которых отделен запятой.) Внутренний
<ul>цикл также создает список и отображает один элемент списка для каждого поля в строке данных.В коде показано, как использовать два типа данных, массив и
charтип данных. Массив необходим, так какFile.ReadAllLinesметод возвращает данные в виде массива. Типcharданных является обязательным, так какSplitметод возвращает значениеarray, в котором каждый элемент имеет типchar. (Сведения о массивах см. в статье "Введение в ASP.NET веб-программирование с помощью синтаксиса Razor".)Запустите страницу в браузере. Отображаются введенные данные для предыдущих примеров.
Подсказка
Отображение данных из файла Microsoft Excel с разделителями-запятыми
Microsoft Excel можно использовать для сохранения данных, содержащихся в электронной таблице, в виде файла с разделителями-запятыми (.csv файла). При этом файл сохраняется в виде обычного текста, а не в формате Excel. Каждая строка в электронной таблице разделена разрывом строки в текстовом файле, а каждый элемент данных разделен запятыми. Код, показанный в предыдущем примере, можно использовать для чтения файла с разделителями-запятыми Excel, просто изменив имя файла данных в коде.
Удаление файлов
Чтобы удалить файлы с веб-сайта, можно использовать File.Delete. В этой процедуре показано, как разрешить пользователям удалять изображение (.jpg файл) из папки изображений , если они знают имя файла.
Замечание
Важно На рабочем веб-сайте обычно ограничивается, кто может вносить изменения в данные. Сведения о настройке членства и способах авторизации пользователей для выполнения задач на сайте см. в разделе "Добавление безопасности и членства" на сайт веб-страниц ASP.NET.
На веб-сайте создайте вложенную папку с именем изображения.
Скопируйте один или несколько .jpg файлов в папку изображений .
В корне веб-сайта создайте файл с именем FileDelete.cshtml.
Замените существующее содержимое следующим образом:
@{ 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>Эта страница содержит форму, в которой пользователи могут ввести имя файла изображения. Они не вводят расширение имени файла.jpg ; Ограничив имя файла таким образом, вы помогаете запретить пользователям удалять произвольные файлы на сайте.
Код считывает имя файла, введенное пользователем, а затем создает полный путь. Чтобы создать путь, код использует текущий путь веб-сайта (как возвращается
Server.MapPathметодом), имя папки изображений , указанное пользователем, и ".jpg" в качестве литеральной строки.Чтобы удалить файл, код вызывает
File.Deleteметод, передав ему полный путь, который вы только что создали. В конце разметки код отображает сообщение подтверждения о том, что файл был удален.Запустите страницу в браузере.
Введите имя файла для удаления и нажмите кнопку "Отправить". Если файл был удален, имя файла отображается в нижней части страницы.
Предоставление пользователям возможности отправки файла
Вспомогательный FileUpload элемент позволяет пользователям отправлять файлы на веб-сайт. В приведенной ниже процедуре показано, как разрешить пользователям отправлять один файл.
Добавьте библиотеку веб-вспомогательных служб ASP.NET на веб-сайт, как описано в разделе "Установка вспомогательных служб" на сайте веб-страниц ASP.NET, если вы не добавили его ранее.
В папке App_Data создайте папку и назовите ее UploadedFiles.
В корневом каталоге создайте файл с именем FileUpload.cshtml.
Замените существующее содержимое на странице следующим образом:
@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>Основная часть страницы использует вспомогательный элемент
FileUpload, чтобы создать окно загрузки и кнопки, с которыми вы, вероятно, знакомы.
Свойства, заданные для вспомогательного
FileUploadэлемента, указывают, что требуется одно поле для отправки файла, и что требуется кнопка " Отправить". (Вы добавите дополнительные поля далее в статье.)Когда пользователь нажимает кнопку "Отправить", код в верхней части страницы получает файл и сохраняет его. Объект
Request, который обычно используется для получения значений из полей формы, также содержитFilesмассив, содержащий отправленный файл (или файлы). Вы можете получить отдельные файлы из определенных позиций в массиве — например, чтобы получить первый загруженный файл, возьмитеRequest.Files[0], чтобы получить второй файл, возьмитеRequest.Files[1], и так далее. (Помните, что при программировании подсчет обычно начинается с нуля.)При получении отправленного файла вы помещаете его в переменную (здесь),
uploadedFileчтобы ее можно было управлять. Чтобы определить имя загруженного файла, нужно получить его свойствоFileName. Однако при загрузке файлаFileNameсодержит оригинальное имя файла пользователя, включая весь путь. Это может выглядеть следующим образом:C:\Users\Public\Sample.txt
Вы не должны добавлять всю эту информацию о пути, поскольку это путь на компьютере пользователя, а не для вашего сервера. Вы просто хотите фактическое имя файла (Sample.txt). Вы можете удалить только файл из пути с помощью
Path.GetFileNameметода, как показано ниже.Path.GetFileName(uploadedFile.FileName)Объект
Path— это утилита, имеющая ряд таких методов, которые можно использовать для удаления путей, их объединения и т. д.Получив имя отправленного файла, вы можете создать новый путь для хранения отправленного файла на веб-сайте. В этом случае вы объединяете
Server.MapPathимена папок (App_Data/UploadedFiles) и только что отрезаемое имя файла, чтобы создать новый путь. Вы можете затем вызвать методSaveAsзагруженного файла, чтобы на самом деле сохранить файл.Запустите страницу в браузере.
Нажмите кнопку "Обзор" , а затем выберите файл для отправки.
Текстовое поле рядом с кнопкой "Обзор " будет содержать путь и расположение файла.
Нажмите кнопку Отправить.
На веб-сайте щелкните правой кнопкой мыши папку проекта и нажмите кнопку "Обновить".
Откройте папку UploadedFiles . Отправленный файл находится в папке.
Предоставление пользователям возможности загрузки нескольких файлов
В предыдущем примере пользователи могут отправлять один файл. Но вы можете использовать вспомогательный FileUpload элемент для отправки нескольких файлов за раз. Это удобно для сценариев, таких как отправка фотографий, где отправка одного файла за раз мучена. (Вы можете прочитать о отправке фотографий в разделе "Работа с изображениями" на сайте веб-страниц ASP.NET.) В этом примере показано, как разрешить пользователям отправлять два за раз, хотя вы можете использовать один и тот же метод для отправки больше, чем это.
Добавьте библиотеку вспомогательных средств ASP.NET на ваш веб-сайт, как описано в разделе "Установка вспомогательных библиотек" на сайте веб-страниц ASP.NET, если вы еще не сделали этого.
Создайте страницу с именем FileUploadMultiple.cshtml.
Замените существующее содержимое на странице следующим образом:
@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>В этом примере вспомогательный
FileUploadэлемент в тексте страницы настроен так, чтобы пользователи отправили два файла по умолчанию. Так какallowMoreFilesToBeAddedзадано значениеtrue, вспомогательная программа отрисовывает ссылку, которая позволяет пользователю добавлять дополнительные поля для загрузки.
Чтобы обработать файлы, отправляемые пользователем, код использует тот же базовый метод, который вы использовали в предыдущем примере, — получите файл,
Request.Filesа затем сохраните его. (Включая различные действия, которые необходимо предпринять, чтобы получить правильное имя и путь к файлу.) Инновация в этот раз заключается в том, что пользователь может загружать несколько файлов, и вы не знаете, сколько именно. Чтобы это выяснить, вы можете получитьRequest.Files.Count.С помощью этого числа вы можете проходить через
Request.Files, извлекать каждый файл по очереди и сохранять его. Если вы хотите выполнить цикл известное количество раз по коллекции, можно использовать циклfor, как показано ниже.for(int i =0; i < numFiles; i++) { var uploadedFile = Request.Files[i]; if (uploadedFile.ContentLength > 0) { fileName = Path.GetFileName(uploadedFile.FileName); // etc. }Переменная
i— это просто временный счетчик, который будет переходить от нуля до заданного верхнего предела. В этом случае верхний предел — это количество файлов. Но поскольку счетчик начинается с нуля, как обычно для сценариев подсчета в ASP.NET, верхний предел на самом деле меньше количества файлов. (При отправке трех файлов число равно нулю до 2.)Переменная
uploadedCountсуммирует все файлы, которые успешно отправлены и сохранены. Этот код учитывает возможность того, что ожидаемый файл может не загрузиться.Запустите страницу в браузере. В браузере отображается страница и два поля загрузки.
Выберите два файла для отправки.
Нажмите кнопку "Добавить другой файл". На странице отображается новое поле загрузки.
Нажмите кнопку Отправить.
На веб-сайте щелкните правой кнопкой мыши папку проекта и нажмите кнопку "Обновить".
Откройте папку UploadedFiles , чтобы просмотреть успешно отправленные файлы.