首页 > 解决方案 > 将文件上传到 S3 存储桶:await fileTransferUtility.UploadAsync(filePath, _bucket) 出现空引用异常

问题描述

我正在尝试将文件上传到 S3 存储桶,但出现空引用异常 await fileTransferUtility.UploadAsync(filePath, _bucket)

public class FileUploadService : IFileUploadService
{
    private readonly string _bucket;

    public FileUploadService()
    {
        _bucket = ConfigurationManager.AppSettings["S3Bucket"];
    }

    public async Task UploadFile(string filePath, CognitoAWSCredentials cred)
    {
        IAmazonS3 client = new AmazonS3Client(cred);
        TransferUtility fileTransferUtility = new TransferUtility(client);
        await fileTransferUtility.UploadAsync(filePath, _bucket);
    }
}

这是异常堆栈跟踪的相关部分:

在 Amazon.S3.Util.BucketRegionDetector.GetUsEast1ClientFromCredentials(ImmutableCredentials 凭证) 在 Amazon.S3.Util.BucketRegionDetector.GetHeadBucketPreSignedUrl(String bucketName, ImmutableCredentials 凭证) 在 Amazon.S3.Util.BucketRegionDetector.d__13.MoveNext() 在 System.Runtime。 CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Amazon.S3.Util.BucketRegionDetector.d__12.MoveNext() ...

不知道我做错了什么,因为我是 AWS 的新手。CognitoAWSCredentials我通过以下方式检索:

string clientId = ConfigurationManager.AppSettings["CLIENT_ID"];
string poolId = ConfigurationManager.AppSettings["USERPOOL_ID"];
RegionEndpoint region = RegionEndpoint.EnumerableAllRegions.First(q => q.SystemName == "us-east-1");
provider = new AmazonCognitoIdentityProviderClient(new AnonymousAWSCredentials(), region);    

CognitoUserPool userPool = new CognitoUserPool(poolId, clientId, provider);
CognitoUser user = new CognitoUser(username, clientId, userPool, provider);

AuthFlowResponse context = await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest()
{
    Password = password
});

CognitoAWSCredentials cred = user.GetCognitoAWSCredentials(poolId, region);

标签: c#amazon-web-servicesamazon-s3amazon-cognito

解决方案


您的凭据对于 UploadAsync 调用无效。

(请参阅:https ://github.com/aws/aws-sdk-net/issues/1166 ,了解为什么会出现空引用异常。)

您应该使用身份池 ID 而不是用户池 ID 调用 GetCognitoAWSCredentials(poolId, region)。请参阅此处的“身份验证后使用 AWS 资源”部分:https ://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/cognito-authentication-extension.html

要避免空引用异常,请在使用 CognitoAWSCredentials 进行任何 S3 调用之前调用 GetCredentialsAsync。就像是:

public async Task UploadFile(string filePath, CognitoAWSCredentials cred)
{
    try
    {
        // AmazonS3Client behaves badly if its GetCredentialsAsync() call throws certain exceptions,
        // so try for ourselves first.  We are doomed anyway if we can't get proper credentials.
        _ = await cred.GetCredentialsAsync();
    }
    catch (Exception e)
    {
        Trace.WriteLine($"Exception getting credentials: {e.Message}");
        throw;
    }

    IAmazonS3 client = new AmazonS3Client(cred);
    TransferUtility fileTransferUtility = new TransferUtility(client);
    await fileTransferUtility.UploadAsync(filePath, _bucket);
}

这样,您可以自己处理来自 GetCredentialsAsync() 的异常。


推荐阅读