Использование ASP.NET Core v.2.1.2 с AWSSDK для S3 (версия 3.3.20.2)
Один и тот же контроллер, два разных маршрута (один с параметром URL и один без). Методы идентичны, за исключением того, что у аргумента url param есть аргумент. Я хочу загрузить файл, но затем отправить его на S3 (и это прекрасно работает в случае отсутствия параметров).
Простое добавление аргумента id приводит к истечению времени ожидания запроса с ошибкой:
"Your socket connection to the server was not read from or written to within the timeout period. Idle connections will be closed."
Это ошибочный запрос:
curl -X POST \
http://localhost:5000/api/post/image/4 \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Postman-Token: c78c7572-8822-4de7-a532-61538df87c85' \
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
-F =@/Users/myusername/Desktop/peace.png
Полагаю, добавление параметра id изменяет HttpContext.Request.Body, но я не вижу этого изменения, когда я запускаю в режиме отладки и добавляю точки останова (поток выглядит точно так же)
Что мне здесь не хватает? Идентичный код, но с удаленным параметром id, работает для обоих маршрутов
Кстати, причина, по которой я хочу использовать параметр id, заключается в том, что после загрузки файла я могу записать идентификатор файла в сообщении как ссылку на запись в AWS
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using BlogApi.Models;
using BlogApi.Services;
namespace BlogApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class PostController : ControllerBase
{
public string AWS_KEY {get; private set;}
public string AWS_SECRET {get; private set;}
private readonly PostContext _context;
private AmazonUploader uploader { get; set; }
public PostController(PostContext context)
{
_context = context;
AWS_KEY = "my_key";
AWS_SECRET = "my_secret";
uploader = new AmazonUploader(AWS_KEY, AWS_SECRET);
}
[HttpPost("image/{id}")]
public string Image(long id)
{
var request = HttpContext.Request;
var fileStream = request.Body;
var contentLength = request.ContentLength;
var contentType = request.ContentType;
string key = Guid.NewGuid().ToString();
var length = contentLength.HasValue ? (long)contentLength : 0;
return uploader.sendMyFileToS3(fileStream, contentType, length, key).Result;
}
[HttpPost]
public string MyFileUpload()
{
var request = HttpContext.Request;
var fileStream = request.Body;
var contentLength = request.ContentLength;
var contentType = request.ContentType;
string key = Guid.NewGuid().ToString();
var length = contentLength.HasValue ? (long)contentLength : 0;
return uploader.sendMyFileToS3(fileStream, contentType, length, key).Result;
}
...
Просто для информации вот код моего класса AmazonUploader
using System;
using System.Diagnostics;
using System.Net;
using System.Threading.Tasks;
using System.IO;
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Transfer;
using Microsoft.Extensions.Configuration;
namespace BlogApi.Services
{
public class AmazonUploader
{
private IAmazonS3 client;
private const string bucketName = "my_bucket";
private static readonly RegionEndpoint bucketRegion = RegionEndpoint.EUWest2;
public AmazonUploader(string AWS_KEY, string AWS_SECRET) {
client = new AmazonS3Client(AWS_KEY, AWS_SECRET, bucketRegion);
}
public async Task<ListObjectsResponse> ListingObjectsAsync()
{
ListObjectsRequest request = new ListObjectsRequest
{
BucketName = bucketName
};
return await client.ListObjectsAsync(request);
}
public async Task<string> sendMyFileToS3(System.IO.Stream inputStream, string contentType, long contentLength, string key)
{
PutObjectRequest request = new PutObjectRequest
{
BucketName = bucketName,
Key = key,
ContentType = contentType,
InputStream = inputStream
};
request.Headers.ContentLength = contentLength;
PutObjectResponse awsResponse = await client.PutObjectAsync(request);
if (awsResponse.HttpStatusCode == HttpStatusCode.OK) {
return key;
} else {
return "error";
}
}
}
}