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

.NET 6 Lambda通过SQS接收S3事件时消息体为空的问题

问题原因与解决方法

你遇到的核心问题是:SQS接收到的消息是经过SNS封装后的结构,而非原始的S3事件JSON。直接按S3事件格式解析自然拿不到数据,而改用S3Event类时,是跳过了SNS/SQS的中间层,直接让Lambda接收S3的原始事件触发,所以能正常解析。

具体原因

当你通过S3→SNS→SQS→Lambda的链路传递事件时,SQS中的消息体并非直接的S3事件内容,而是SNS的消息结构。典型的SNS消息格式大致如下:

{
  "Type": "Notification",
  "MessageId": "xxxx-xxxx-xxxx",
  "TopicArn": "arn:aws:sns:region:account:topic-name",
  "Message": "{\"Records\":[{\"s3\":{...}}]}", // 这里才是原始的S3事件JSON
  "Timestamp": "2024-xx-xxTxx:xx:xx.xxxZ",
  "SignatureVersion": "1",
  // 其他SNS相关字段
}

你之前的代码直接把整个消息体当成S3事件解析,自然找不到Records字段,导致消息体看似“为空”或解析失败。

修正后的代码示例

你需要先解析SNS的消息结构,取出Message字段后,再解析成S3事件:

方法1:使用AWS Lambda SDK提供的SNSEvent类(推荐)

using Amazon.Lambda.SQSEvents;
using Amazon.Lambda.SNSEvents;
using Newtonsoft.Json;

public async Task FunctionHandler(SQSEvent sqsEvent, ILambdaContext context)
{
    foreach (var sqsRecord in sqsEvent.Records)
    {
        // 先解析SNS消息
        var snsEvent = JsonConvert.DeserializeObject<SNSEvent>(sqsRecord.Body);
        var s3EventJson = snsEvent.Records[0].Sns.Message;
        
        // 再解析S3事件
        var s3Event = JsonConvert.DeserializeObject<Amazon.Lambda.S3Events.S3Event>(s3EventJson);
        var s3Record = s3Event.Records[0];
        
        var bucketName = s3Record.S3.Bucket.Name;
        var objectKey = s3Record.S3.Object.Key;
        
        // 后续处理逻辑
    }
}

方法2:手动用JObject解析

using Amazon.Lambda.SQSEvents;
using Newtonsoft.Json.Linq;

public async Task FunctionHandler(SQSEvent sqsEvent, ILambdaContext context)
{
    var sqsRecord = sqsEvent.Records[0];
    var snsMessage = JObject.Parse(sqsRecord.Body);
    
    // 取出SNS包裹的原始S3事件消息
    var s3EventJson = snsMessage["Message"].ToString();
    var s3Event = JObject.Parse(s3EventJson);
    
    var bucketName = s3Event["Records"][0]["s3"]["bucket"]["name"].ToString();
    var objectKey = s3Event["Records"][0]["s3"]["object"]["key"].ToString();
    
    // 后续处理逻辑
}

为什么用S3Event类直接触发能正常工作

当你把Lambda的触发器直接设为S3事件时,Lambda接收的是原始的S3事件JSON,没有经过SNS的封装,所以可以直接用Amazon.Lambda.S3Events.S3Event类反序列化,直接获取record.S3.Bucket.Name等字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:37:21