[英]Internal Server Error returned when accessing aws Serverless API deployed to AWS API gateway
I'm trying to deploy an API that manipulates the AWS DynamoDB database. 我正在尝试部署可操纵AWS DynamoDB数据库的API。 I used the serverless API template provided by the AWS .Net SDK.
我使用了AWS .Net SDK提供的无服务器API模板。 The .Net Core API works fine locally, but will return an "Internal server error" whenever I try to access the API after I published it to AWS Lambda.
.Net Core API在本地运行良好,但是在将其发布到AWS Lambda之后,每当我尝试访问该API时,都会返回“内部服务器错误”。
In the CloudWatch Logs Insights, the log message returns something like this 在CloudWatch Logs Insights中,日志消息返回如下内容
An exception was thrown when the constructor for type 'ProjectAPI.Controllers.MyController' was invoked.
调用'ProjectAPI.Controllers.MyController'类型的构造函数时,引发了异常。 Check inner exception for more details.: LambdaException
检查内部异常以获取更多详细信息。:LambdaException
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor)
在System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,布尔publicOnly,布尔wrapExceptions,布尔&canBeCached,RuntimeMethodHandleInternal&ctor)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean skipCheckThis, Boolean fillCache)
在System.RuntimeType.CreateInstanceSlow处(布尔publicOnly,布尔wrapExceptions,布尔skipCheckThis,布尔fillCache)
In the constructor of MyController I instantiate a service and that service will fetch credentials and setup the DynamoDBContext. 在MyController的构造函数中,我实例化了一个服务,该服务将获取凭据并设置DynamoDBContext。
In MyController: 在MyController中:
private readonly IMyService _myService;
public CoffeeController(IMyService myService){
_myService = myService;
}
In MyService: IMyService 在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");
}
In Startup.cs: 在Startup.cs中:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSingleton<IMyService, MyService>();
}
I presume there is something wrong when fetching the credentials, but i'm not sure how to do it appropriately in .Net Core environment. 我认为获取凭据时出了点问题,但是我不确定如何在.Net Core环境中适当地进行操作。
I assume "Hackathon-coffee"
is referring to a credentials profile stored on your local development environment. 我假设
"Hackathon-coffee"
是指存储在本地开发环境中的凭据配置文件。 That profile won't exist in the Lambda environment. 该配置文件在Lambda环境中将不存在。
In Lambda you most likely want to use the credentials for the IAM Role that is assigned to the Lambda function when you created it. 在Lambda中,您很可能希望使用在创建Lambda函数时分配给IAM角色的凭据。
Basically when running in Lambda you want to construct your AmazonDynamoDBClient
without passing in a AWSCredentials
. 基本上,当在Lambda中运行时,您想要构建
AmazonDynamoDBClient
而不传递AWSCredentials
。 The SDK will automatically resolve the credentials for the assigned role. SDK会自动为分配的角色解析凭据。 This is also true for region parameter in the constructor.
对于构造函数中的region参数也是如此。 If you construct an
AmazonDynamoDBClient
with the empty constructor it will configure the client with credentials for the IAM role and the region the function is running in. 如果您使用空构造函数构造一个
AmazonDynamoDBClient
,它将为客户端配置IAM角色和运行该功能的区域的凭证。
A handy trick I use in my code sometimes to figure out if I'm running in Lambda is check to see if the LAMBDA_TASK_ROOT
environment variable is set. 有时,我会在代码中使用一个方便的技巧来判断我是否在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 });
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.