我尝试在两个资源之间移动我的对象。 首先,我执行 CopyRequest,然后执行 DeleteRequest。但是当我尝试移动对象时,出现以下错误:
Header 'x-amz-tagging-directive' with value 'COPY' not implemented
。
我尝试在创建 CopyObjectRequest 实例后删除标头,但没有名称相似的标头。另外,在创建 CopyObjectRequest 的新实例时,我没有看到任何配置。
S3客户端的配置和实例
var config = new AmazonS3Config
{
ServiceURL = SabiartConfig.SabiartS3Domain
};
var credentials = new BasicAWSCredentials(SabiartConfig.SabiartS3Key, SabiartConfig.SabiartS3Secret);
_client = new AmazonS3Client(credentials, config);
await _fileService.MoveToBucket(fileIdString, SabiartConfig.SabiartS3TemporaryBucketName,
SabiartConfig.SabiartS3PublicBucketName);
移动代码:
public async Task MoveToBucket(string fileIdString, string originBucket, string destinationBucket)
{
var request = new CopyObjectRequest
{
SourceBucket = originBucket,
SourceKey = fileIdString,
DestinationBucket = destinationBucket,
DestinationKey = fileIdString
};
await _client.CopyObjectAsync(request);
await DeleteAsync(fileIdString, originBucket);
}
堆栈:
Amazon.S3.AmazonS3Exception: Header 'x-amz-tagging-directive' with value 'COPY' not implemented
---> Amazon.Runtime.Internal.HttpErrorResponseException: Exception of type 'Amazon.Runtime.Internal.HttpErrorResponseException' was thrown.
at Amazon.Runtime.HttpWebRequestMessage.ProcessHttpResponseMessage(HttpResponseMessage responseMessage)
at Amazon.Runtime.HttpWebRequestMessage.GetResponseAsync(CancellationToken cancellationToken)
at Amazon.Runtime.Internal.HttpHandler`1.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.RedirectHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.Unmarshaller.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.S3.Internal.AmazonS3ResponseHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.ErrorHandler.InvokeAsync[T](IExecutionContext executionContext)
--- End of inner exception stack trace ---
at Amazon.Runtime.Internal.HttpErrorResponseExceptionHandler.HandleExceptionStream(IRequestContext requestContext, IWebResponseData httpErrorResponse, HttpErrorResponseException exception, Stream responseStream)
at Amazon.Runtime.Internal.HttpErrorResponseExceptionHandler.HandleExceptionAsync(IExecutionContext executionContext, HttpErrorResponseException exception)
at Amazon.Runtime.Internal.ExceptionHandler`1.HandleAsync(IExecutionContext executionContext, Exception exception)
at Amazon.Runtime.Internal.ErrorHandler.ProcessExceptionAsync(IExecutionContext executionContext, Exception exception)
at Amazon.Runtime.Internal.ErrorHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.Signer.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.CredentialsRetriever.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.S3.Internal.AmazonS3ExceptionHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.MetricsHandler.InvokeAsync[T](IExecutionContext executionContext)
at Sabiart.Gallery.Application.Services.FileServiceS3.MoveToBucket(String fileIdString, String originBucket, String destinationBucket) in E:\Projetos\sabiart\sabia.backend\src\Sabiart.Gallery.Application\Services\FileServiceS3.cs:line 116
根据 CloudFlare 文档,仍然不支持
x-amz-tagging-directive
标头:
❌ x-amz-标记指令
CopyObject
API 本身并不严格需要 x-amz-tagging-directive
标头,因为 S3 内部默认为 COPY
;如果未发送标头,CloudFlare 可能会在幕后执行无操作,但 .NET SDK 不提供省略此标头的方法。它总是为此标头设置一个值,以确定是否需要复制对象的标签。
你可以从源代码中看到这一点:
if (copyObjectRequest.IsSetTagSet())
{
request.Headers.Add(S3Constants.AmzHeaderTagging, AmazonS3Util.TagSetToQueryString(copyObjectRequest.TagSet));
request.Headers.Add(S3Constants.AmzHeaderTaggingDirective, TaggingDirective.REPLACE.Value);
}
else
{
request.Headers.Add(S3Constants.AmzHeaderTaggingDirective, TaggingDirective.COPY.Value);
}
不幸的是,在 CloudFlare 支持此标头之前,您需要手动
GetObject
和 PutObject
跨越对象。