【问题标题】:No RegionEndpoint or ServiceURL configured未配置 RegionEndpoint 或 ServiceURL
【发布时间】:2017-12-16 18:18:19
【问题描述】:

我正在编写代码以将文件上传到 AWS S3 并收到此异常:

AmazonClientException:未配置 RegionEndpoint 或 ServiceURL

我的代码:

Console.WriteLine("ready to upload");
AWSCredentials credentials;
credentials = new BasicAWSCredentials(accessKeyID.Trim(), secretKey.Trim());
AmazonS3Client s3Client = new AmazonS3Client(accessKeyID.Trim(), secretKey.Trim(), Amazon.RegionEndpoint.USEast1);
Console.WriteLine("Successful verification");
Console.WriteLine("Check if the bucket exists");
if (!CheckBucketExists(s3Client, bucketName))
{
    s3Client.PutBucket(bucketName);
    Console.WriteLine("create bucket");
}
TransferUtility utility = new TransferUtility();
Console.WriteLine("Upload  Directory......");
//exception here
utility.UploadDirectory(@"E:\telerikFile\13ginabdfglil.com", bucketName);

例外:

Amazon.Runtime.AmazonClientException: No RegionEndpoint or ServiceURL configured
  Amazon.Runtime.ClientConfig.Validate()
  Amazon.S3.AmazonS3Config.Validate()
  Amazon.Runtime.AmazonServiceClient..ctor(AWSCredentials credentials, ClientConfig config)
  Amazon.S3.AmazonS3Client..ctor()
  Amazon.S3.Transfer.TransferUtility..ctor()
  Telerik2Amazon.Program.UploadFile()

我该怎么办?

【问题讨论】:

  • 对于 S3 或 EC2 等服务,必须指定端点。所以new AmazonS3Client(credentials, RegionEndpoint.USEast1) 应该可以工作。

标签: .net amazon-web-services amazon-s3 aws-sdk aws-sdk-net


【解决方案1】:

错误的简短回答...

Amazon.Runtime.AmazonClientException:未配置 RegionEndpoint 或 ServiceURL

...在我的例子中是在构造客户端对象时指定一个区域(对我来说是AmazonSimpleEmailServiceClient)。

假设您使用的是BasicAWSCredentials,那么试试这个:

var credentials = new BasicAWSCredentials(accessKeyID, secretKey);

new AmazonS3Client(credentials, RegionEndpoint.USEast1);

//                              ^^^^^^^^^^^^^^^^^^^^^^  add this

【讨论】:

    【解决方案2】:

    首先,您不应该对 aws 凭据进行硬编码。

    我遇到了类似的错误。原来这是由于 .Net Core 的变化:

    .NET Core 中最大的变化之一是删除了 ConfigurationManager 以及标准的 app.config 和 web.config 文件

    https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-netcore.html

    对于快速而肮脏的方法,您可以在您的机器上创建凭据配置文件,请参阅https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html

    例如C:\Users\<USERNAME>\.aws\credentials 在 Windows 上

    [default]
    aws_access_key_id = your_access_key_id
    aws_secret_access_key = your_secret_access_key
    

    然后在您的代码中,您可以执行以下操作:

    var dbClient = new AmazonDynamoDBClient(new StoredProfileAWSCredentials(), 
                         RegionEndpoint.USEast1);
    

    更复杂的方式是:https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-netcore.html#net-core-configuration-builder

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();
    }
    

    appsettings.Development.json

    {
      "AWS": {
        "Profile": "local-test-profile",
        "Region": "us-west-2"
      }
    }
    
    
    var options = Configuration.GetAWSOptions();
    IAmazonS3 client = options.CreateServiceClient<IAmazonS3>();
    

    【讨论】:

    • 仍然应该避免对该区域进行硬编码..因为如果您将其移至欧洲或亚洲..您将连接到错误的东西。在 AWS 上,它只使用执行代码的角色访问和区域。如果需要,配置文件确实可以“覆盖”这一点。但这种情况很少发生 - 使用“更多参与的方式”,这确实是更受欢迎的方式.. 并不是那么困难
    • 我发现的问题是我需要使用 AmazonEC2Client 中的 DryRun() 方法,而 IAmazonEC2 不提供该方法。如果我尝试将 CreateServiceClient() 与 AmazonEC2Client 一起使用,则无法创建客户端,并引发“对象未设置为引用”错误:(
    【解决方案3】:

    在 Asp.Net 中,可以通过将此行添加到 Web.config 来修复此错误:

    <add key="AWSRegion" value="us-east-1" />
    

    为 AWSSDK.SimpleEmail v3.3 工作

    【讨论】:

    • 改用/.aws/credentials 文件。它可以使用Visual Studio AWS Toolkit 轻松创建。这是有道理的,因为当您部署时,EC2/Lambda 实例使用角色“元数据”并获取它需要的所有信息。抱歉 -1 导致人们复制并粘贴此内容而不了解 AWS 凭证的工作原理(例如,我自己)
    【解决方案4】:

    我在为使用 S3 客户端的 Lambda 运行测试时收到此错误。我通过简单地提供带有~/.aws/config 中定义的区域的默认配置文件来解决了该错误:

    [default]
    region = us-west-1
    

    无需更改 Lambda 代码。当然 YMMV 取决于你的情况。

    【讨论】:

      【解决方案5】:

      可以使用我的访问密钥 ID 和密钥。
      因此我放弃使用 TransferUtility 类并选择另一个名为 PutObjectRequest 的类来上传我的文件
      attontion: PutObjectRequest的属性Key,它的目录名和文件名必须等于本地文件的目录名和文件名。
      这里的代码:

              String s3Path = "987977/Baby.db";
              Console.WriteLine("Ready to upload");
              AWSCredentials credentials;
              credentials = new BasicAWSCredentials(accessKeyID.Trim(), secretKey.Trim());
              AmazonS3Client s3Client = new AmazonS3Client(accessKeyID.Trim(), secretKey.Trim(), Amazon.RegionEndpoint.USEast1);
              Console.WriteLine("Successful verification");
              Console.WriteLine("Check: if the bucket exists");
              if (!CheckBucketExists(s3Client, bucketName))
              {
                  s3Client.PutBucket(bucketName);
                  Console.WriteLine("Creat bucket");
              }
              string localPath = @"E:\telerikFile\987977\Baby.db";
              PutObjectRequest obj = new PutObjectRequest();
              var fileStream = new FileStream(localPath, FileMode.Open, FileAccess.Read);
        //      obj.FilePath= @"E:\telerikFile\987977\Baby.db";
              obj.InputStream = fileStream;
              obj.BucketName = bucketName;
              obj.Key = s3Path;
             // obj.ContentBody = "This is sample content...";
              obj.CannedACL = S3CannedACL.PublicRead;
              Console.WriteLine("uploading");
              // default to set public right  
              s3Client.PutObject(obj);
      

      【讨论】:

      • 出于某种原因,即使使用这种方法也会给我同样的错误,直到我在文件 C:\Users\\.aws\credentials 上添加了默认配置文件。我实际上不使用该文件上的凭据,但如果它丢失它会引发错误。无论如何,它似乎都需要您对该文件的默认配置文件。
      【解决方案6】:

      从 .NET Core 开始,不再使用 web.configapp.config,而是使用 ConfigurationBuilder,它可以从多个不同来源检索配置。

      .NET 的 Web 模板使用 Host.CreateDefaultBuilder(args),它依赖于环境变量和 appsettings.json 文件,对于其他应用程序,可以执行以下操作:

      IConfiguration configuration = new ConfigurationBuilder()
                      .SetBasePath(Directory.GetCurrentDirectory())
                      .AddJsonFile(APPSETTINGS, optional: false, reloadOnChange: true)
                      .AddEnvironmentVariables()
                      .Build();
      

      这将从appsettings.json 文件以及环境变量中检索配置,并允许您按如下方式检索它们:

      var region = configuration["AWS_REGION"];
      

      AWS 开发工具包将使用此配置来检索通过任何 ASP.NET Core 应用程序中的依赖注入检索的服务的区域。对于 Lambda,您需要手动构建一个 ServiceCollection 才能使其工作,这可以这样做。

      private readonly ServiceProvider serviceProvider;
      
      public Function()
      {
          var serviceCollection = new ServiceCollection();
          serviceCollection.AddSingleton<IAmazonDynamoDB, AmazonDynamoDBClient>();
          serviceProvider = serviceCollection.BuildServiceProvider();
      }
      
      public void FunctionHandler(string input, LambdaContext context)
      {
          var dynamodb = serviceProvider.GetService<IAmazonDynamoDB>();
          // Business logic here
      }
      

      这种方法应该足以满足几乎所有用例。如果您遇到此问题,请尝试解决问题,而不是尝试下面的回退。

      接下来的内容只是为了完整性,但您真的不需要它。

      当使用上述方法失败时,您可以依靠AWSConfigs 静态来明确设置您的环境变量。使用下面的方法,我们可以重用我们现有的配置,无论是在 appsettings.json 还是在环境变量中。

      AWSConfigs.AWSRegion = configuration["AWS_REGION"];
      

      【讨论】:

      • 谢谢,AWSConfigs.AWSRegion = configuration["ap-southeast-2"]; 是我在我们的代码管道构建服务器上运行模拟和单元测试所需要的。
      • @thinkOfaNumber 非常厌倦在单元测试中使用它,尤其是当您像我们一样并行运行测试时。因为这个静态字段是跨线程共享的,所以将它设置在一个地方会在任何地方设置它,并可能导致您的测试变得不确定。
      • 如果所有单元测试都使用相同的区域,那应该不是问题,对吧?我没有测试更改区域,只是尝试模拟 AmazonIotDataClient,这样我就可以在不实际调用 PublishAsync 的情况下测试我的服务。
      • 对,应该可以正常工作。我们还进行了测试该区域有效性的测试,这要求其中一些设置不同的值,从而导致问题。
      • 您可以使用 Nuget:AWSSDK.Extensions.NETCore.Setup,然后像这样连接您的 AWS 服务:``` services.TryAddAWSService(configuration.GetAWSOptions("sqs")) ; ``` 这假设你的 appsettings.json 有这样的部分:``` { "sqs": { "ServiceURL": "sqs.ap-southeast-2.amazonaws.com" } } ``
      【解决方案7】:

      我也有这个问题,没有任何帮助,aws 是最糟糕的,如此复杂,而且他们的文档低于 microsft,难怪 Azure 正在占据市场份额

      【讨论】:

        【解决方案8】:

        如果你使用TransferUtility(),试试这个:

        var credentials = new BasicAWSCredentials(accessKeyID, secretKey);
        
        var S3Client = new AmazonS3Client(credentials, RegionEndpoint.USEast1);
        
        this._transferUtility = new TransferUtility(S3Client);
        

        【讨论】:

          猜你喜欢
          • 2020-05-29
          • 2020-07-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多