aws lambda function using serverless template of asp.net core

Viewed 720

I don't have enough knowledge of aws but my company asked me to do a job which I guess is what AWS Lambda does perfectly. The requirement is I have to create a service that has an endpoint that needs to be called twice a day. The approach I followed is I created a serverless web API through visual studio and created API gateway endpoint for each endpoint. Then added a trigger through cloud watch events to run it twice a day but whenever the function is triggered I get this error.

Object reference not set to an instance of an object.: NullReferenceException
   at Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction.MarshallRequest(InvokeFeatures features, APIGatewayProxyRequest apiGatewayRequest, ILambdaContext lambdaContext)
   at Amazon.Lambda.AspNetCoreServer.AbstractAspNetCoreFunction`2.FunctionHandlerAsync(TREQUEST request, ILambdaContext lambdaContext)
   at lambda_method(Closure , Stream , Stream , LambdaContextInternal )
2 Answers

I have the same issue and could fix it recently.

If you use Lambda with ASP.NET Core, you should have LambdaEntryPoint class to handle all the requests. Try to override MarshallRequest method in this class, add logging and see what you have in apiGatewayRequest parameter. The code can look something like this:

protected override void MarshallRequest(InvokeFeatures features, APIGatewayProxyRequest apiGatewayRequest, ILambdaContext lambdaContext)
{
    LambdaLogger.Log($"Request path: {apiGatewayRequest.Path}");
    LambdaLogger.Log($"Request path parameters: {apiGatewayRequest.PathParameters}");
    LambdaLogger.Log($"Request body: {apiGatewayRequest.Body}");
    LambdaLogger.Log($"Request request context: {apiGatewayRequest.RequestContext}");
    base.MarshallRequest(features, apiGatewayRequest, lambdaContext);
}

In my case, all these values were nulls. The reason for it was in using Amazon EventBridge for keeping Lambda online to avoid a cold start. If you also use EventBridge, try to configure the request there properly. If not, you can try to update MarshalRequest the following way:

protected override void MarshallRequest(InvokeFeatures features, APIGatewayProxyRequest apiGatewayRequest, ILambdaContext lambdaContext)
{
    if(apiGatewayRequest.RequestContext == null) //Or other property
    {
        return;
    }

    base.MarshallRequest(features, apiGatewayRequest, lambdaContext);
}

A few days ago I had the same problem. Grigory Zhadko’s answer helped me a lot by knowing which method I should overwrite. LambdaEntryPoint requires for any other process to instantiate an ApiGatewayProxiRequest object manually (for example, eventBridge). The configuration I implemented to fix the problem is as follows.

protected override void MarshallRequest(InvokeFeatures features, APIGatewayProxyRequest apiGatewayRequest, ILambdaContext lambdaContext)
    {
        var endpoint = "my/endpoint";

        if (apiGatewayRequest != null && apiGatewayRequest?.RequestContext == null)
        {
            apiGatewayRequest.Path = $"/{endpoint}";
            apiGatewayRequest.Resource = $"/{endpoint}";
            apiGatewayRequest.HttpMethod = "ANY METHOD";
            apiGatewayRequest.RequestContext = new APIGatewayProxyRequest.ProxyRequestContext
            {
                Path = $"/path/{endpoint}", // your path request
                Identity = new APIGatewayProxyRequest.RequestIdentity
                {
                    ClientCert = new APIGatewayProxyRequest.ProxyRequestClientCert
                    {
                        Validity = new APIGatewayProxyRequest.ClientCertValidity()
                    }
                },
                ResourcePath = $"/{basePath}{eventEntpoint}",
                HttpMethod = "ANY METHOD",
                Authorizer = new APIGatewayCustomAuthorizerContext()
            };
        }

        base.MarshallRequest(features, apiGatewayRequest, lambdaContext);
    }
Related