Содержание
В предыдущей части мы научились отправлять файлы клиенту и скачивать файлы на компьютер пользователя. Сегодня рассмотрим обратную операцию — загрузку файлов на сервер. Загрузка файлов на сервер в ASP.NET Core немногим сложнее, так как все же для этой операции нам придётся немного вспомнить работу с формами в HTML и научиться отправлять запросы POST на сервер.
IForm File
Все загружаемые на сервер файлы в ASP.NET Core представлены типом IFormFile с помощью которого мы можем получить некоторые сведения о файле, а также получить поток для работы с данными файла. У IFormFile определены следующие свойства:
Content |
Возвращает необработанный заголовок Content-Disposition отправленного файла. |
Content |
Возвращает необработанный заголовок Content-Type отправленного файла. |
File |
Возвращает имя файла из заголовка Content-Disposition. |
Headers |
Возвращает словарь заголовков отправленного файла. |
Length |
Возвращает длину файла в байтах. |
Name |
Возвращает имя поля формы из заголовка Content-Disposition. |
Как можно увидеть из представленной таблицы, три свойства IFormFile из шести основаны на значениях заголовка Content-Disposition, с которым мы уже знакомы по опыту отправки файлов пользователю. Также у IFormFile определены три метода:
Copy |
Копирует содержимое отправленного файла в поток, указанный в параметрах метода. |
Copy |
Асинхронно копирует содержимое отправленного файла в поток, указанный в параметрах метода. |
Open |
Открывает поток запроса для чтения отправленного файла. |
Теперь попробуем использовать эти свойства и методы для загрузки файлов на сервер ASP.NET Core. Для начала, создадим простую HTML-форму для отправки файлов на сервер.
HTML-форма для загрузки файлов на сервер
Создадим пустой проект ASP.NET Core и добавим в него две папки: wwwroot и html следующим образом:
Теперь добавим в папку html файл index.html. Чтобы не писать вручную основной html-код страницы в блокноте, можно добавить этот файл, используя Visual Studio:
В проект будет добавлен html-файл со следующим содержанием:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
</body>
</html>
Теперь добавим в этот файл html-форму:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Загрузка файла на сервер ASP.NET Core</title>
</head>
<body>
<p>Выберите файл для загрузки</p>
<form method="post" enctype="multipart/form-data">
<input type="file" name="uploads" /><br>
<input type="submit" value="Загрузить" />
</form>
</body>
</html>
В этой форме мы определили одно поле input с типом file для указания загружаемого файла, кнопку «Загрузить» клик по которой будет выполнять запрос POST на сервер. Также, чтобы вместе с формой отправлялись данные файла мы указали у формы тип данных «multipart/form-data». В запущенном приложении эта форма будет выглядеть следующим образом:
Теперь напишем небольшой компонент middleware который будет принимать и обрабатывать запросы от пользователя.
Middleware для загрузки файла на сервер
Наше приложение должно обрабатывать два типа запросов: GET — для отправки пользователю формы для загрузки файла и POST — для получения файла от пользователя. Мы уже вкратце изучали обработку запроса пользователя, поэтому не будем повторяться и сразу напишем следующий middleware (ниже представлен весь исходный код приложения):
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Run(async context =>
{
context.Response.ContentType = "text/html; charset=utf-8";
HttpRequest request = context.Request;
if (request.Method == "POST")
{
//создаем папку uploads для загружаемых файлов
var path = Path.Combine(app.Environment.ContentRootPath, "uploads");
Directory.CreateDirectory(path);
//получаем коллекцию загружаемых файлов
IFormFileCollection files = request.Form.Files;
foreach (IFormFile file in files)
{
string fileFullPath = Path.Combine(path, file.FileName);
// сохраняем файл в папку uploads
using (var fileStream = new FileStream(fileFullPath, FileMode.Create))
{
await file.CopyToAsync(fileStream);
}
}
await context.Response.WriteAsync("<b>Файлы загружены</b>");
}
else
{
await context.Response.SendFileAsync(@"wwwroot\html\index.html");
}
});
app.Run();
}
}
Middleware действует следующим образом: во-первых, проверяется метод запроса:
if (request.Method == "POST")
если метод POST, то считаем, что пользователь загружает файл на сервер, если же нет, то мы отправляем пользователю наш файл index.html с формой:
await context.Response.SendFileAsync(@"wwwroot\html\index.html");
Во-вторых, при обработке запроса POST мы создаем директорию в которой будем сохранять файлы:
var path = Path.Combine(app.Environment.ContentRootPath, "uploads"); Directory.CreateDirectory(path);
файлы сохраняются в папку uploads, которая будет находится в корневой папке проекта. Далее, мы получаем коллекцию файлов формы
IFormFileCollection files = request.Form.Files;
Несмотря на то, что мы предусмотрели загрузку всего одного файла на сервер, тем не менее, код формы может измениться и, например, в форме будут отправляться не один, а 10 файлов, поэтому в middleware предусмотрен цикл foreach в котором перебираются все элементы коллекции (объекты, реализующие IFormFile) и каждый файл сохраняется на диск:
foreach (IFormFile file in files)
{
string fileFullPath = Path.Combine(path, file.FileName);
// сохраняем файл в папку uploads
using (var fileStream = new FileStream(fileFullPath, FileMode.Create))
{
await file.CopyToAsync(fileStream);
}
}
После того как файлы сохранены, пользователю выводится сообщение об успешной загрузке:
await context.Response.WriteAsync("<b>Файлы загружены</b>");
Ниже представлены работа нашего приложения.
Вид приложения сразу после запуска:
Успешная загрузка файла
Вид обозревателя решений Visual Studio после загрузки файла на сервер:
Итого
Сегодня мы научились загружать файлы на сервер ASP.NET Core и немного подробнее изучили работу с запросами пользователя, в частности, использовали свойства Method и Form для обработки запроса. Загружаемые на сервер файлы представляются в виде коллекции IFormFileCollection в которой каждый элемент — это один файл, представленный типом IFormFile. Стоит также напомнить, что в ASP.NET Core имеется штатный middleware для работы со статическими файлами о котором мы поговорим далее.




