<div><img src="https://top-fwz1.mail.ru/counter?id=3548135;js=na" style="position:absolute;left:-9999px;" alt="Top.Mail.Ru" /></div>
Публичное облако на базе VMware с управлением через vCloud Director
Вход / Регистрация

Как настроить и использовать S3-хранилище с ASP.NET

Команда Timeweb Cloud
Команда Timeweb Cloud
Наши инженеры, технические писатели, редакторы и маркетологи
18 марта 2025 г.
20
14 минут чтения
Средний рейтинг статьи: 4.3

При разработке веб-приложений в первую очередь нужно решить, где будут храниться файлы, с которыми работает приложение. В традиционных веб-приложениях файлы обычно размещаются на сервере, который обслуживает приложение. Однако этот метод имеет свои ограничения: сложно эффективно управлять большим количеством данных и обеспечить их безопасность. Более современным и удобным решением является использование облачного хранилища, которое позволяет легко сохранять и получать файлы через интернет. Одним из вариантов облачного хранилища является объектное хранилище S3.

Объектное хранилище — это тип хранения данных, где информация сохраняется как отдельные объекты, что позволяет эффективно управлять большими объемами данных. В нашем случае объекты — это файлы, которые мы будем загружать и скачивать с облака. В этой статье мы покажем, как настроить S3-хранилище Timeweb Cloud и подключить его к вашему веб-приложению.

Наш проект разрабатывается на .NET 9 — одной из самых последних версий фреймворка от Microsoft. Эта платформа обеспечивает высокую производительность веб-приложений, особенно при использовании ASP.NET, что позволяет эффективно обрабатывать пользовательские запросы через интернет.

В этой статье мы рассмотрим следующие ключевые этапы настройки нашего проекта:

  • Создание проекта в Timeweb Cloud — создадим проект и объектное хранилище в Timeweb Cloud и настроим его для хранения наших файлов.

  • Развертывание ASP.NET-проекта — создадим веб-приложение на ASP.NET и подготовим его для работы, настроив все необходимые компоненты для обработки запросов.

  • Установка необходимых NuGet-пакетов — NuGet — это система для управления библиотеками и пакетами в .NET. Мы подключим библиотеки, которые помогут работать с S3-хранилищем, чтобы мы могли загружать и скачивать файлы.

  • Добавление поддержки Scalar — подключим поддержку OpenAPI с помощью Scalar, чтобы упростить тестирование нашего API (интерфейса для взаимодействия с приложением).

  • Настройка переменных окружения — для надежного хранения ключей доступа к S3-хранилищу настроим переменные окружения, чтобы хранить конфиденциальную информацию в безопасном месте, а не прямо в коде.

  • Создание минимального Docker-контейнера — Docker — это инструмент, который позволяет упаковать приложение в контейнер, что упрощает его развертывание на разных серверах. Мы создадим контейнер, чтобы проще развернуть наше приложение в облаке.

  • Подключение к S3 API — научимся работать с S3 API, чтобы загружать и скачивать файлы.

  • Разработка контроллеров — добавим эндпоинты (адреса, по которым приложение будет получать запросы) для работы с хранилищем, чтобы пользователи могли загружать и скачивать файлы через интернет.

Весь процесс будет пошаговым, и в конце вы получите работающий API, который будет взаимодействовать с облачным хранилищем S3, позволяя загружать и скачивать файлы. 

s3

Шаг 1. Создание проекта в Timeweb Cloud

  1. Перейдите в панель управления Timeweb Cloud и создайте новый проект.

Image7

  1. В панели управления создайте S3-хранилище. Выберите подходящий тариф (для тестового развертывания достаточно минимального конфигурации) и перейдите в бакет — контейнер для хранения объектов.

Image1

  1. Перейдите в сам бакет, чтобы просмотреть его конфигурацию. Он будет доступен внутри вашего проекта или в разделе «Хранилище S3».

Image4

  1. Сохраните три ключевых значения: 

    1. Название бакета
    2. S3 Access Key
    3. S3 Secret Access Key

Image5

Шаг 2. Развертывание ASP.NET-проекта

Выполнение этого и следующих шагов также представлено на скринкасте.

Откройте консоль и создайте директорию для проекта:

mkdir timeweb-s3-api

Затем перейдите в эту директорию:

cd timeweb-s3-api

Инициализируйте проект командой:

dotnet new webapi

Проект будет создан с версией .NET 9. Чтобы убедиться в этом, откройте файл с расширением .csproj и найдите строку:

<TargetFramework>net9.0</TargetFramework>

Для минимальной конфигурации файл Program.cs должен выглядеть так:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi();
var app = builder.Build();
app.MapOpenApi();
app.Run();

Шаг 3. Установка NuGet-пакетов

Для работы с S3 и нужными библиотеками установите необходимые пакеты, поочередно выполнив следующие команды:

dotnet add package AWSSDK.Extensions.NETCore.Setup --version 4.0.0-preview
dotnet add package AWSSDK.S3 --version 4.0.0-preview
dotnet add package DotNetEnv --version 3.1.1
dotnet add package Microsoft.AspNetCore.OpenApi --version 9.0.2
dotnet add package Scalar.AspNetCore --version 2.0.25

После установки пакетов дождитесь их загрузки и подтвердите установку последнего пакета, снова нажав Enter.

Затем соберите проект, выполнив команду:

dotnet build

Шаг 4. Добавление файла GlobalUsings.cs

Создайте файл GlobalUsings.cs в корне проекта и добавьте в него следующие пространства имен:

global using Scalar.AspNetCore;
global using DotNetEnv;
global using Amazon.S3;
global using Microsoft.Extensions.Options;
global using Microsoft.AspNetCore.Mvc;
global using Amazon.S3.Model;
global using System.Net;

Этот файл позволит избежать дублирования директив using в каждом файле проекта, обеспечивая доступ к необходимым библиотекам везде, где это потребуется.

Шаг 5. Добавление Scalar для поддержки API

Добавьте поддержку Scalar API, чтобы упростить тестирование приложения.

Для этого откройте Program.cs и сразу после строки var app = builder.Build(); добавьте:

app.MapScalarApiReference();

Это создаст страницу http://localhost/scalar, где веб-клиент сможет видеть доступные API-эндпоинты — адреса, по которым можно отправлять запросы.

Шаг 6. Настройка переменных окружения

Создайте файл .env в корневой папке проекта. В этом файле будут храниться переменные окружения — настройки, которые приложение будет использовать при работе. 

Замените значения в скобках на свои данные для подключения к бакету.

Пример содержимого файла:

AWS_BUCKET_NAME=[Название бакета]
AWS_ACCESS_KEY=[S3 Access Key]
AWS_SECRET_ACCESS_KEY=[S3 Secret Access Key]
AWS_SERVICE_URL=https://s3.timeweb.cloud
ASPNETCORE_URLS=http://+:80

В итоге файл будет выглядеть подобным образом:

Image2

Добавьте в проект переменные окружения. Для этого откройте Program.cs и вставьте следующий код сразу после строки var builder = WebApplication.CreateBuilder(args):

Env.Load();
builder.Configuration.AddEnvironmentVariables();

Шаг 7. Создание Docker-контейнера

Создайте Dockerfile в корневой папке проекта. Этот файл нужен, чтобы Docker мог собрать образ — упакованную версию приложения со всеми зависимостями, готовую для запуска в любой среде.

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /app
EXPOSE 80
COPY . .
RUN dotnet restore timeweb-s3-api.csproj
RUN dotnet publish timeweb-s3-api.csproj -c Release -o /app/publish

FROM mcr.microsoft.com/dotnet/aspnet:9.0
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "timeweb-s3-api.dll"]

Добавьте файл docker-compose.yml со следующим содержимым:

services:
  backend:
    container_name: backend
    build:
      context: .
      dockerfile: Dockerfile
    env_file:
      - .env
    ports:
      - 80:80
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

Шаг 8. Подключение к S3 API

Создайте файл S3Options.cs в корневой папке проекта. В нем будут храниться настройки для подключения к S3-хранилищу. Добавьте в него следующий код:

public class S3Options
{
    public string AccessKey { get; set; } = null!;
    public string SecretKey { get; set; } = null!;
    public string ServiceUrl { get; set; } = null!;
    public string BucketName { get; set; } = null!;
}

Далее для того, чтобы использовать настройки окружения в нашем приложении, в файл Program.cs после строки builder.Services.AddOpenApi(); добавьте код:

builder.Services.Configure<S3Options>(options =>
{
    options.AccessKey = Environment.GetEnvironmentVariable("AWS_ACCESS_KEY") ?? "";
    options.SecretKey = Environment.GetEnvironmentVariable("AWS_SECRET_ACCESS_KEY") ?? "";
    options.ServiceUrl = Environment.GetEnvironmentVariable("AWS_SERVICE_URL") ?? "";
    options.BucketName = Environment.GetEnvironmentVariable("AWS_BUCKET_NAME") ?? "";
});
builder.Services.AddSingleton<IAmazonS3>(sp =>
{
    var options = sp.GetRequiredService<IOptions<S3Options>>().Value;
    return new AmazonS3Client(options.AccessKey, options.SecretKey, new AmazonS3Config
    {
        ServiceURL = options.ServiceUrl,
        ForcePathStyle = true
    });
});

Он нужен, чтобы передать настройки для работы с S3-хранилищем (например, ключи доступа и адрес сервиса) и сделать их доступными в приложении. Это называется «внедрение зависимостей» — способ передавать нужные параметры в разные части кода без их явного указания в каждом месте.

Шаг 9. Разработка контроллеров для работы с S3 в .NET 9

Для работы с объектным хранилищем S3 от Timeweb Cloud в проекте необходимо создать контроллер S3Controller. Он будет обрабатывать загрузку, получение и удаление изображений в S3.

Создание контроллера

В корневой директории создаем папку Controllers, а в ней — файл S3Controller.cs. Добавьте в него следующий код:

[ApiController]
[Route("api/s3")]
public class S3Controller : ControllerBase
{
   private readonly S3Options _s3Options;
   private readonly IAmazonS3 _s3;

   public S3Controller(IOptions<S3Options> options, IAmazonS3 s3)
   {
       _s3Options = options.Value;
       _s3 = s3;
   }

[HttpPost("image/{id}")]
public async Task<ActionResult<PutObjectResponse>> Upload([FromRoute] int id, [FromForm(Name = "Data")] IFormFile file)
   {
      var request = new PutObjectRequest
      {
         BucketName = _s3Options.BucketName,
         Key = $"{id}",
         ContentType = file.ContentType,
         InputStream = file.OpenReadStream(),
      };
      var response = await _s3.PutObjectAsync(request);
      return response.HttpStatusCode == HttpStatusCode.OK ? Ok(response) : BadRequest();
      }

[HttpGet("image/{id}")]
public async Task<IActionResult> GetImage([FromRoute] int id)
{
   var objectRequest = new GetObjectRequest
   {
      BucketName = _s3Options.BucketName,
      Key = $"{id}"
   };

   var response = await _s3.GetObjectAsync(objectRequest);
   if (response.HttpStatusCode == HttpStatusCode.OK)
   return File(response.ResponseStream, response.Headers["Content-Type"]);

        return BadRequest();
    }

    [HttpDelete("image/{id}")]
    public async Task<IActionResult> DeleteImage([FromRoute] int id)
    {
        var objectRequest = new DeleteObjectRequest
        {
            BucketName = _s3Options.BucketName,
            Key = $"{id}"
        };
        var response = await _s3.DeleteObjectAsync(objectRequest);
        return response.HttpStatusCode == HttpStatusCode.NoContent ? NoContent() : BadRequest();
    }
}

Контроллер помечается атрибутами:

  • [ApiController] — указывает, что этот класс является контроллером API.

  • [Route("api/s3")] — задает маршрут для запросов, начинающихся с api/s3.

Также контроллер использует зависимости:

  • S3Options — объект конфигурации с настройками доступа к S3.

  • IAmazonS3 — клиент для взаимодействия с S3.

Они передаются через конструктор с внедрением зависимостей (IOptions<S3Options> для конфигурации и IAmazonS3 для работы с S3).

Разберем методы работы с файлами:

Метод [HttpPost("image/{id}")] используется для загрузки изображения в S3.

При вызове метода создается запрос PutObjectRequest, в котором указываются:

  • id — идентификатор файла (например, ID объекта в базе данных).
  • IFormFile file — полученный файл из multipart/form-data.

Входные параметры метода:

  • BucketName — название бакета,
  • Key — имя файла в S3 (в данном случае переданный id),
  • ContentType — тип файла,
  • InputStream — поток загружаемого файла.

Запрос передается в PutObjectAsync, который выполняет загрузку. Если ответ OK (200), загрузка прошла успешно, иначе возвращается ошибка.

Метод [HttpGet("image/{id}")] позволяет получить изображение из S3.

При вызове метода создается запрос GetObjectRequest, в котором указываются:

  • BucketName — название бакета,
  • Key — идентификатор файла.

Входной параметр метода:

  • id — идентификатор файла в S3.

Метод [HttpDelete("image/{id}")] удаляет изображение из S3.

При вызове метода создается запрос DeleteObjectRequest, содержащий:

  • BucketName — название бакета,
  • Key — идентификатор файла.

Входной параметр метода:

  • id — идентификатор файла в S3.

После этого выполняется DeleteObjectAsync. Если статус ответа NoContent (204), файл успешно удален, иначе возвращается ошибка.

Добавление маршрутов в приложение

Чтобы контроллер начал работать, необходимо добавить в файле Program.cs после app.MapOpenApi(); следующие строки:

app.MapControllers();
app.UseRouting();

Этот метод регистрирует маршруты для всех контроллеров в приложении, включая S3Controller.

Также перед строкой var app = builder.Build(); добавьте: 

builder.Services.AddControllers();

Вызов функции сообщает ASP.NET Core, что в приложении будут использоваться контроллеры и их нужно зарегистрировать. Без этого контроллеры не будут работать, даже если маршруты настроены.

Шаг 10. Тестирование с помощью Docker и Postman

Для тестирования нашего API, которое теперь доступно по адресу http://localhost, мы будем использовать два инструмента: Postman и Scalar. В обоих случаях мы будем отправлять HTTP-запросы на следующие эндпоинты:

  • GET для получения файла по ID
  • POST для загрузки файла
  • DELETE для удаления файла

Эти запросы будут выполняться по шаблону http://localhost/api/s3/image/{id}, где {id} — это уникальный идентификатор изображения, с которым мы будем взаимодействовать.

Сначала необходимо запустить контейнер, чтобы приложение стало доступно. Для этого в терминале, находясь в директории проекта, выполните команду:

docker-compose up --build -d

Это создаст и запустит Docker-контейнер, собрав все необходимые компоненты приложения.

Тестирование с помощью Postman

Postman — это инструмент для тестирования API. Мы будем использовать его для отправки запросов на наш сервер.

Откройте Postman и введите URL запроса в формате http://localhost/api/s3/image/{id}, где {id} — это значение, которое вы хотите использовать для тестирования (например, 1).

Убедитесь, что запрос использует правильный HTTP-метод (GET, POST или DELETE).

Пример GET-запроса

URL: http://localhost/api/s3/image/1

Этот запрос будет пытаться получить файл с ID 1. Ответ будет содержать файл (если он существует) или сообщение об ошибке.

Пример POST-запроса (Загрузка файла)

URL: http://localhost/api/s3/image/1

В теле запроса:

  • Тип данных: form-data.
  • Ключ: Data — сюда нужно добавить файл для загрузки.

Это запрос для загрузки изображения с ID 1 в хранилище S3. В form-data вы должны прикрепить файл, который хотите загрузить.

Пример DELETE-запроса (Удаление файла)

URL: http://localhost/api/s3/image/1

Этот запрос удаляет файл с ID 1 из S3-хранилища.

Пример из Postman продемонстрирован на картинке ниже.

Image3

Тестирование с помощью Scalar 

Scalar — это инструмент для тестирования API с использованием OpenAPI, который подключен для удобства. Он позволяет увидеть список всех доступных эндпоинтов и взаимодействовать с ними прямо из браузера.

При использовании Scalar выполните следующие действия.

  1. Откройте браузер и перейдите по адресу:
http://localhost/scalar

Здесь отобразится список всех доступных эндпоинтов, включая /api/s3/image/{id} для работы с изображениями.

  1. В интерфейсе Scalar выберите нужный HTTP-метод (GET, POST или DELETE).
  2. Настройте запрос. Вы можете задать параметры запроса, например, указать id изображения, и отправить запрос непосредственно из Scalar

Примеры запросов в Scalar:

GET-запрос

URL: http://localhost/api/s3/image/1

Этот запрос пытается получить файл с ID 1. Если файл существует, Scalar вернет его с оригинальным Content-Type, иначе — сообщение об ошибке.

POST-запрос (Загрузка файла)

URL: http://localhost/api/s3/image/1

В теле запроса:

  • Тип данных: form-data
  • Ключ: Data — здесь нужно прикрепить файл для загрузки

Этот запрос загружает изображение с ID 1 в хранилище S3.

DELETE-запрос

URL: http://localhost/api/s3/image/1

Этот запрос удаляет файл с ID 1 из S3-хранилища.

Пример из Scalar продемонстрирован на картинке ниже.

Image6

Тестирование через Postman и Scalar поможет убедиться, что все эндпоинты работают правильно и файлы могут быть загружены, получены и удалены с S3-хранилища.

Надежное облако для ваших проектов

Заключение

Мы успешно разработали и настроили приложение для работы с файлами в объектном хранилище S3 от Timeweb Cloud: создали хранилище, настроили проект на .NET 9, подключили необходимые библиотеки для работы с S3 и добавили поддержку Scalar. Мы также настроили переменные окружения и создали Docker-контейнер.

Теперь наше приложение позволяет загружать, получать и удалять файлы через API, взаимодействуя с объектным хранилищем S3, что делает его удобным и безопасным для использования в реальных проектах.

Хотите внести свой вклад?
Участвуйте в нашей контент-программе за
вознаграждение или запросите нужную вам инструкцию
img-server
18 марта 2025 г.
20
14 минут чтения
Средний рейтинг статьи: 4.3
Пока нет комментариев