C# Can';在使用route param进行发布时,不要将文件流发送到AWS(不使用route param可以正常工作)
使用ASP.NET Core v.2.1.2和AWSSDK for S3(版本3.3.20.2) 同一控制器,两个不同的路由(一个带url参数,一个不带url参数)。除了带有url参数的方法有一个参数外,其他方法都是相同的。我想上传一个文件,但随后将其发送到S3(这在无参数的情况下可以正常工作) 仅添加id参数会导致对aws的请求超时,并出现错误:C# Can';在使用route param进行发布时,不要将文件流发送到AWS(不使用route param可以正常工作),c#,asp.net-core,async-await,asp.net-core-mvc,aws-sdk,C#,Asp.net Core,Async Await,Asp.net Core Mvc,Aws Sdk,使用ASP.NET Core v.2.1.2和AWSSDK for S3(版本3.3.20.2) 同一控制器,两个不同的路由(一个带url参数,一个不带url参数)。除了带有url参数的方法有一个参数外,其他方法都是相同的。我想上传一个文件,但随后将其发送到S3(这在无参数的情况下可以正常工作) 仅添加id参数会导致对aws的请求超时,并出现错误: “您与服务器的套接字连接在超时期间未被读取或写入。空闲连接将被关闭。” 这是失败的请求: curl -X POST \ http://local
“您与服务器的套接字连接在超时期间未被读取或写入。空闲连接将被关闭。”
这是失败的请求:
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参数存在的原因是,一旦上传文件,我就可以在帖子上记录文件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;
}
...
这里是我的AmazonPloader类的代码,仅供参考
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";
}
}
}
}
使用系统;
使用系统诊断;
Net系统;
使用System.Threading.Tasks;
使用System.IO;
使用亚马逊;
使用Amazon.S3;
使用Amazon.S3.0模型;
使用Amazon.S3.Transfer;
使用Microsoft.Extensions.Configuration;
命名空间BlogApi.Services
{
公共级亚马逊阅读器
{
私人IAmazonS3客户;
private const string bucketName=“my_bucket”;
专用静态只读RegionEndpoint bucketRegion=RegionEndpoint.EUWest2;
公共AmazonPloader(字符串AWS\U密钥,字符串AWS\U密钥){
客户端=新AmazonS3Client(AWS_密钥、AWS_密钥、bucketRegion);
}
公共异步任务列表对象同步()
{
ListObjectsRequest请求=新建ListObjectsRequest
{
BucketName=BucketName
};
返回wait client.ListObjectsAsync(请求);
}
公共异步任务sendMyFileToS3(System.IO.Stream inputStream,string contentType,long contentLength,string key)
{
PutObjectRequest=新的PutObjectRequest
{
BucketName=BucketName,
键=键,
ContentType=ContentType,
InputStream=InputStream
};
request.Headers.ContentLength=ContentLength;
PutObjectResponse awsResponse=等待客户端。PutObjectAsync(请求);
if(awsResponse.HttpStatusCode==HttpStatusCode.OK){
返回键;
}否则{
返回“错误”;
}
}
}
}
我刚刚找到了问题所在
a) 我犯了一个错误,不知何故让邮递员添加了一个额外的内容类型标题:application/x-www-form-encoded
b) 即使我没有错误地添加该标题,实际的内容类型也是错误的——我是以多部分/表单数据的形式发送的,这不起作用——我需要以二进制形式发送它。如果我在《邮递员》中为请求正文选择了该选项,它会起作用。对于不起作用的请求,您会调用什么url?谢谢您的回复。我发布到,如果我在方法中设置了断点,它就会触发。我已经在问题中添加了失败请求的curl。我建议检查并比较有效请求和无效请求的原始请求。只是出于兴趣-你会怎么做?设置断点时,我无法确定如何“查看”流。身体对象看起来是一样的。无论如何,谢谢你的帮助,我刚刚发现了一个问题,那就是a)我犯了一个愚蠢的错误,不知何故让邮递员添加了一个
内容类型:application/x-www-form-encoded
的标题;b)即使我没有错误地添加该标题,内容类型错误-我以multipart/form data
的形式发送,但不起作用-我需要以二进制的形式发送。如果我在Postman中为请求主体选择了该选项,它将起作用。