Одной из распространенных задач веб-приложения является загрузка файлов на сервер. Рассмотрим, как загружать файлы в веб-приложение на ASP.NET Core.
Все загружаемые файлы в ASP.NET Core представлены типом IFormFile из пространства имен Microsoft.AspNetCore.Http
.
Соответственно для получения отправленного файла в контроллере необходимо использовать IFormFile. Затем с помощью методов IFormFile мы можем произвести различные манипуляции
файлом - получит его свойства, сохранить, получить его поток и т.д. Некоторые его свойства и методы:
ContentType
: тип файла
FileName
: название файла
Length
: размер файла
CopyTo/CopyToAsync
: копирует файл в поток
OpenReadStream
: открывает поток файла для чтения
Для тестирования данной возможности определим в проекте папку html, в которой создадим файл index.html
Определим в файле index.html следующий код:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>METANIT.COM</title> </head> <body> <h2>Выберите файл для загрузки</h2> <form action="upload" method="post" enctype="multipart/form-data"> <input type="file" name="uploads" /><br> <input type="file" name="uploads" /><br> <input type="file" name="uploads" /><br> <input type="submit" value="Загрузить" /> </form> </body> </html>
В данном случае форма содержит набор элементов с типом file, через которые можно выбрать файлы для загрузки. В данном случае на форме три таких элемента, но их может быть и меньше и больше. А благодаря установке атрибута формы enctype="multipart/form-data" браузер будет знать, что вместе с формой надо передать файлы.
Отправляться файлы будут в запросе типа POST на адрес "/upload".
Теперь в файле Program.vb определим код, который будет получать загружаемые файлы:
Imports Microsoft.AspNetCore.Builder Imports Microsoft.AspNetCore.Http Module Program Sub Main(args As String()) Dim builder = WebApplication.CreateBuilder(args) Dim app = builder.Build() app.Run(Async Function(context As HttpContext) As Task Dim response = context.Response Dim request = context.Request response.ContentType = "text/html; charset=utf-8" If request.Path.Value = "/upload" AndAlso request.Method = "POST" Then Dim files As IFormFileCollection = request.Form.Files 'путь к папке, где будут храниться файлы Dim uploadPath = $"{IO.Directory.GetCurrentDirectory()}/uploads" ' создаем папку для хранения файлов IO.Directory.CreateDirectory(uploadPath) For Each file In files 'путь к папке uploads Dim fullPath = $"{uploadPath}/{file.FileName}" 'сохраняем файл в папку uploads Using fileStream = New IO.FileStream(fullPath, IO.FileMode.Create) Await file.CopyToAsync(fileStream) End Using Next Await response.WriteAsync("Файлы успешно загружены") Else Await response.SendFileAsync("html/index.html") End If End Function) app.Run() End Sub End Module
Здесь если запрос приходит по адресу "/upload", а сам запрос представляет запрос типа POST, то приложение получает коллекцию загруженных файлов с помощью свойства Request.Form.Files, которое представляет тип IFormFileCollection:
Dim files As IFormFileCollection = request.Form.Files
Далее определяем каталог для загружаемых файлов (предполагается, что файлы будут храниться в каталоге "uploads", которая располагается в папке приложения)
Dim uploadPath = $"{IO.Directory.GetCurrentDirectory()}/uploads"
Если такой папки нет, то создаем ее. Затем перебираем всю коллекцию файлов.
For Each file In files
Каждый отдельный файл в этой коллекции представляет тип IFormFile. Для копирования файла
в нужный каталог создается поток FileStream, в который записывается файл с помощью метода CopyToAsync
.
Using fileStream = New IO.FileStream(fullPath, IO.FileMode.Create) Await file.CopyToAsync(fileStream) End Using
Если запрос идет по другому адресу и/или не представляет тип POST, то отправляем клиенту html-страницу index.html.
Обратимся к приложению и выберем файлы для загрузки:
И после успешной загрузки нам отобразиться соответствующее сообщение:
А в каталоге проекта будет создана папка uploads, в которой появятся загуженные файлы: