You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6 Web API部署Lambda后无法处理SQS队列请求

.NET 6 Web API转Lambda后,SQS触发报空引用异常的解决方法

问题场景

  • 基于.NET 6 Core Web API构建项目,通过builder.Services.AddAWSLambdaHosting(LambdaEventSource.HttpApi);转为Lambda并通过CLI部署
  • POSTMAN调用Lambda函数正常,但通过AWS控制台的SQS队列发送消息触发时,抛出空引用异常

异常日志

2023-02-01T00:38:06.905Z    04b8dce2-d17c-5125-88d3-80b167d862bd    fail    System.NullReferenceException: Object reference not set to an instance of an object.
   at Amazon.Lambda.AspNetCoreServer.APIGatewayHttpApiV2ProxyFunction.MarshallRequest(InvokeFeatures features, APIGatewayHttpApiV2ProxyRequest apiGatewayRequest, ILambdaContext lambdaContext)
   at Amazon.Lambda.AspNetCoreServer.AbstractAspNetCoreFunction`2.FunctionHandlerAsync(TREQUEST request, ILambdaContext lambdaContext)
   at Amazon.Lambda.RuntimeSupport.HandlerWrapper.<>c__DisplayClass26_0`2.<GetHandlerWrapper>b__0.MoveNext()
--- End of stack trace from previous location ---
   at Amazon.Lambda.RuntimeSupport.LambdaBootstrap.InvokeOnceAsync(CancellationToken cancellationToken)

测试消息

POSTMAN/SQS直接发送的消息

{
    "nameOnCard": "Samuel Ojo",
    "cardNumber": "5256854950074930",
    "cvv": "283",
    "expiryMonth": "04",
    "expiryYear": "27",
    "postalCode": "101232",
    "billingAddress": "Lagos",
    "billingState": "Lagos",
    "billingCity": "Lagos",
    "billingCountry": "Nigeria",
    "awsSettings": {
        "topicArn": [redacted],
        "targetArn": [redacted],
        "snsTopicFilter": "VirtualCard"
    }
}

SQS模板消息

{
  "Records": [
    {
      "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
      "receiptHandle": "MessageReceiptHandle",
      "body": "{\"sourceAccount\": \"0123445599\",\"destinationAccount\": \"1838494040\",\"bankCode\": \"011\",\"amount\": 200,\"awsSettings\": {\"topicArn\": [redacted],\"targetArn\": [redacted],\"snsTopicFilter\": \"FundTransfer\"}}",
      "attributes": {
        "ApproximateReceiveCount": "1",
        "SentTimestamp": "1523232000000",
        "SenderId": "123456789012",
        "ApproximateFirstReceiveTimestamp": "1523232000001"
      },
      "messageAttributes": {},
      "md5OfBody": "{{{md5_of_body}}}",
      "eventSource": "aws:sqs",
      "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue",
      "awsRegion": "us-east-1"
    }
  ]
}

Program.cs代码

using VirtualCardService.Middlewares;
using VirtualCardService.Services.Contracts;

var builder = WebApplication.CreateBuilder(args);

#region Add Services to Container

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<IVirtualCardService, VirtualCardService.Services.Implementations.VirtualCardService>();
builder.Services.AddAWSLambdaHosting(LambdaEventSource.HttpApi);
#endregion

var app = builder.Build();

#region Configure Pipeline

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.Use((context, next) =>
{
    context.Request.EnableBuffering();
    return next();
});

app.UseRouting();
app.UseMiddleware<HttpLoggerMiddleware>();
app.UseMiddleware<ExceptionMiddleware>();

app.UseAuthorization();
app.MapControllers();
#endregion

app.Run();

问题原因及解决方法

原因

当前Lambda通过LambdaEventSource.HttpApi配置为仅支持HttpApi触发,而SQS触发的事件格式与HttpApi请求结构完全不兼容。APIGatewayHttpApiV2ProxyFunction尝试将SQS事件转换为ASP.NET Core请求时,找不到预期的HttpApi请求字段,从而抛出空引用异常。

解决步骤

  1. 修改Lambda处理逻辑,支持多事件源
    不能仅依赖AddAWSLambdaHosting的HttpApi模式,需要自定义Lambda入口函数,分别处理HttpApi请求和SQS事件:

    • 创建自定义Lambda入口类,继承APIGatewayHttpApiV2ProxyFunction处理Http请求,同时添加SQS事件处理方法。
  2. 示例修改方案
    移除Program.cs中的builder.Services.AddAWSLambdaHosting(LambdaEventSource.HttpApi);,新增Lambda入口类:

    // LambdaEntryPoint.cs
    using Amazon.Lambda.AspNetCoreServer;
    using Amazon.Lambda.SQSEvents;
    using Microsoft.AspNetCore.Hosting;
    using VirtualCardService.Services.Contracts;
    
    namespace VirtualCardService;
    
    public class LambdaEntryPoint : APIGatewayHttpApiV2ProxyFunction
    {
        protected override void Init(IWebHostBuilder builder)
        {
            builder.ConfigureServices(services =>
            {
                // 注册原有服务
                services.AddControllers();
                services.AddScoped<IVirtualCardService, Services.Implementations.VirtualCardService>();
            }).Configure(app =>
            {
                // 配置原有管道逻辑
                if (app.Environment.IsDevelopment())
                {
                    app.UseSwagger();
                    app.UseSwaggerUI();
                }
                app.UseHttpsRedirection();
                app.UseRouting();
                app.UseMiddleware<HttpLoggerMiddleware>();
                app.UseMiddleware<ExceptionMiddleware>();
                app.UseAuthorization();
                app.MapControllers();
            });
        }
    
        // 处理SQS事件的方法
        public async Task HandleSQSAsync(SQSEvent sqsEvent, ILambdaContext context)
        {
            using var scope = ServiceProvider.CreateScope();
            var cardService = scope.ServiceProvider.GetRequiredService<IVirtualCardService>();
    
            foreach (var record in sqsEvent.Records)
            {
                // 解析消息体并调用业务逻辑
                context.Logger.LogInformation($"Processing SQS message: {record.Body}");
                // 替换为你的业务处理代码
                // await cardService.YourBusinessMethod(record.Body);
            }
        }
    }
    

    部署时指定Lambda处理器:

    • HttpApi触发:VirtualCardService::VirtualCardService.LambdaEntryPoint::FunctionHandlerAsync
    • SQS触发:VirtualCardService::VirtualCardService.LambdaEntryPoint::HandleSQSAsync
  3. 简化替代方案
    如果业务允许,可拆分两个Lambda函数:一个专门处理HttpApi请求,另一个处理SQS事件,共享业务逻辑层代码,避免混合处理的复杂度。

内容的提问来源于stack exchange,提问作者Samuel Babbs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 03:40:22