访问部署到AWS API网关的AWS无服务器API时返回内部服务器错误

时间:2019-08-16 03:16:06

标签: c# api asp.net-core amazon-dynamodb aws-serverless

我正在尝试部署可操纵AWS DynamoDB数据库的API。我使用了AWS .Net SDK提供的无服务器API模板。 .Net Core API在本地运行良好,但是在将其发布到AWS Lambda之后,每当我尝试访问该API时,都会返回“内部服务器错误”。

在CloudWatch Logs Insights中,日志消息返回类似

的内容
  

当类型的构造函数抛出异常   调用了“ ProjectAPI.Controllers.MyController”。检查内部异常以获取更多详细信息。:LambdaException

     

在System.RuntimeTypeHandle.CreateInstance(运行时类型,布尔publicOnly,布尔wrapExceptions,布尔&canBeCached,RuntimeMethodHandleInternal和ctor)

     

在System.RuntimeType.CreateInstanceSlow(布尔publicOnly,布尔wrapException,布尔skipCheckThis,布尔fillCache)

在MyController的构造函数中,我实例化了一个服务,该服务将获取凭据并设置DynamoDBContext。

在MyController中:

private readonly IMyService _myService;
public CoffeeController(IMyService myService){ 
     _myService = myService;
}

在MyService中:IMyService

private readonly DynamoDBContext _context;

public CoffeeService()
{
      var chain = new CredentialProfileStoreChain();
      AWSCredentials awsCredentials;
      if (chain.TryGetAWSCredentials("Hackathon-coffee", out awsCredentials)){
            AmazonDynamoDBClient client = new AmazonDynamoDBClient(awsCredentials, RegionEndpoint.APSoutheast2);
            _context = new DynamoDBContext(client, new DynamoDBContextConfig { ConsistentRead = true, SkipVersionCheck = true });

      }else
            LambdaLogger.Log("Cannot Fetch Credentials");
}

在Startup.cs中:

public void ConfigureServices(IServiceCollection services)
{
  services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  services.AddSingleton<IMyService, MyService>();
}

我认为获取凭据时出了点问题,但是我不确定如何在.Net Core环境中适当地做到这一点。

1 个答案:

答案 0 :(得分:0)

我假设"Hackathon-coffee"是指存储在本地开发环境中的凭据配置文件。该配置文件在Lambda环境中将不存在。

在Lambda中,您很可能希望使用在创建Lambda函数时分配给IAM角色的凭据。

基本上,在Lambda中运行时,您希望构造AmazonDynamoDBClient而不必传递AWSCredentials。 SDK会自动为分配的角色解析凭据。对于构造函数中的region参数也是如此。如果您使用空的构造函数构造AmazonDynamoDBClient,它将为客户端配置IAM角色和运行该功能的区域的凭据。

我有时在代码中使用的一种方便的技巧来确定我是否在Lambda中运行,请检查是否设置了LAMBDA_TASK_ROOT环境变量。

private readonly DynamoDBContext _context;

public CoffeeService()
{
      if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("LAMBDA_TASK_ROOT")))
      {
         var chain = new CredentialProfileStoreChain();
         AWSCredentials awsCredentials;
         if (chain.TryGetAWSCredentials("Hackathon-coffee", out awsCredentials))
         {
            AmazonDynamoDBClient client = new AmazonDynamoDBClient(awsCredentials, RegionEndpoint.APSoutheast2);
            _context = new DynamoDBContext(client, new DynamoDBContextConfig { ConsistentRead = true, SkipVersionCheck = true });

         }
         else
         {
            LambdaLogger.Log("Cannot Fetch Credentials");
         }
      }
      else
      {
         // Use credentials from IAM Role and region the function is running in.
         AmazonDynamoDBClient client = new AmazonDynamoDBClient();
         _context = new DynamoDBContext(client, new DynamoDBContextConfig { ConsistentRead = true, SkipVersionCheck = true });
      }
}