首次部署.NET Core 3.1 C# Lambda遇Handler无法触发及空引用异常
你的问题根源很明确:Lambda入口配置和处理函数的类型完全不匹配。你继承了APIGatewayProxyFunction(这是AWS用来托管ASP.NET Core Web应用的基类,专门处理API Gateway的代理请求),但却在serverless.template里指定了自定义的FunctionHandlerZ作为入口——这个函数期望接收string类型输入,可API Gateway触发时传入的是APIGatewayProxyRequest对象,类型不匹配直接导致序列化失败,抛出NullReferenceException,你的自定义函数根本没机会执行。
下面给你两种解决方案:一种修复你现有的ASP.NET Core Lambda应用,另一种从零构建更轻量的HelloWorld Lambda,都不需要依赖AWS Toolkit。
方案一:修复现有ASP.NET Core Lambda应用
如果你想保留ASP.NET Core框架(方便后续扩展成Web API),按以下步骤调整:
- 修正serverless.template的Handler配置
把Handler改成APIGatewayProxyFunction自带的处理方法,这是基类专门用来转发API Gateway请求到ASP.NET Core的入口:
"Handler": "aspDemo3B::aspDemo3B.LambdaEntryPoint::FunctionHandlerAsync"
- 移除自定义的FunctionHandlerZ
APIGatewayProxyFunction模式下,所有请求都会通过ASP.NET Core的路由系统处理,不需要单独写Lambda处理函数。你可以在Startup.cs里添加简单的测试接口:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello from ASP.NET Core Lambda!"); }); endpoints.MapGet("/greet/{name}", async context => { var name = context.Request.RouteValues["name"]?.ToString() ?? "Guest"; await context.Response.WriteAsync($"Hello {name}!"); }); }); }
- 重新部署
执行命令重新部署:
dotnet lambda deploy-serverless
部署完成后,访问API Gateway提供的URL就能看到响应了。
方案二:从零构建轻量HelloWorld Lambda(无需ASP.NET Core)
如果只是需要一个极简的HelloWorld,用纯Lambda函数更简单:
步骤1:创建Lambda项目
打开终端执行命令:
dotnet new lambda.EmptyFunction --name SimpleHelloWorld --framework netcoreapp3.1 cd SimpleHelloWorld/src/SimpleHelloWorld
步骤2:修改Lambda处理函数
打开Function.cs,替换为适配API Gateway的代码:
using System; using System.Collections.Generic; using Amazon.Lambda.Core; [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] namespace SimpleHelloWorld { public class Function { // 处理API Gateway的Proxy请求 public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context) { context.Logger.LogLine("HelloWorld Lambda triggered!"); // 可以从请求里获取参数,比如查询字符串 var name = request.QueryStringParameters?.GetValueOrDefault("name") ?? "World"; return new APIGatewayProxyResponse { StatusCode = 200, Body = $"{{\"message\": \"Hello {name}!\"}}", Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } } }; } } // 定义API Gateway请求/响应的必要模型 public class APIGatewayProxyRequest { public Dictionary<string, string> QueryStringParameters { get; set; } } public class APIGatewayProxyResponse { public int StatusCode { get; set; } public string Body { get; set; } public Dictionary<string, string> Headers { get; set; } } }
步骤3:配置serverless.template
回到项目根目录(含serverless.template的文件夹),修改资源配置:
"Resources": { "SimpleHelloWorldFunction": { "Type": "AWS::Serverless::Function", "Properties": { "Handler": "SimpleHelloWorld::SimpleHelloWorld.Function::FunctionHandler", "Runtime": "dotnetcore3.1", "CodeUri": "", "MemorySize": 256, "Timeout": 30, "Policies": [ "AWSLambdaBasicExecutionRole" ], "Events": { "HelloApi": { "Type": "Api", "Properties": { "Path": "/hello", "Method": "GET" } } } } } }
步骤4:部署到AWS
执行部署命令(替换为你的AWS区域):
dotnet lambda deploy-serverless --region us-east-1 --stack-name SimpleHelloWorldStack
步骤5:测试
部署完成后,控制台会输出API Gateway的URL,访问https://{api-id}.execute-api.{region}.amazonaws.com/Prod/hello?name=MattG就能看到自定义的问候响应了。
关键注意事项
- API Gateway触发Lambda时,处理函数的参数必须匹配
APIGatewayProxyRequest类型,不能随便用string,否则必出类型不匹配错误。 - 确保你的AWS CLI已经通过
aws configure配置了正确的权限和区域。 - .NET Core 3.1已进入维护期,若允许的话建议升级到.NET 6+(AWS Lambda完全支持),但以上步骤对3.1完全兼容。
内容的提问来源于stack exchange,提问作者MattG

