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

C#中Mailjet邮件发送异常:返回200未送达,事务消息为空

问题排查与解决方案:.NET Core中Mailjet邮件发送失败

核心问题分析

你的情况大概率是平台配置未完全生效 + 代码版本/字段缺失的混合问题,以下分步骤排查并给出修正方案:


一、优先排查平台配置

  1. 域名验证状态
    确认已添加的域名完成了DKIM、SPF、DMARC的全部验证(Mailjet域名管理页面会显示验证状态)。未验证的域名会导致邮件被静默拦截,无任何投递记录。
  2. 发件人地址验证
    即使域名验证通过,单个发件人地址(如mymail@mydomain.com)也需要点击Mailjet发送的验证邮件完成确认,否则无法作为发件人使用。
  3. 账户模式检查
    确认账户是否处于Sandbox模式:Sandbox模式下仅允许发送到预验证的收件人列表,且不会实际投递邮件。可在Mailjet账户设置中切换到生产模式。
  4. API密钥权限
    使用的API密钥需具备邮件发送权限,子密钥可能被限制了功能,建议先用主密钥测试。

二、代码问题修正

1. 事务邮件代码问题(第二种方案)

原代码存在两个关键问题:

  • 未打印完整错误信息,仅输出response无法看到具体失败原因;
  • 缺少纯文本邮件部分(WithTextPart),部分邮件网关会拒绝无纯文本的邮件。

修正后的代码:

var client = new MailjetClient(apiKey, secretKey)
{
    // 指定API版本,避免版本兼容问题
    Version = ApiVersion.V3_1
};

var email = new TransactionalEmailBuilder()
    .WithFrom(new SendContact("mymail@mydomain.com", "Mailjet Sender"))
    .WithSubject("Test Transactional Email")
    .WithHtmlPart("<h1>Hello from Mailjet</h1>")
    .WithTextPart("Hello from Mailjet") // 必须添加纯文本部分
    .WithTo(new SendContact("your-verified-recipient@example.com")) // 确保收件人已验证(Sandbox模式下)
    .Build();

var response = await client.SendTransactionalEmailAsync(email);

// 打印完整响应信息
if (response.IsSuccessStatusCode)
{
    Console.WriteLine($"发送成功!消息ID: {response.Messages[0].To[0].MessageID}");
}
else
{
    Console.WriteLine($"错误状态码: {response.StatusCode}");
    Console.WriteLine($"错误详情: {response.GetErrorInfo()}");
    Console.WriteLine($"错误消息: {response.GetErrorMessage()}");
}

2. 推广邮件代码问题(第三种方案)

原代码的核心问题是使用了v3版本的Send.Resource,而Mailjet当前推荐使用v3.1版本的SendV31.Resource,导致请求被解析异常(返回200但无实际处理)。此外,营销邮件需添加退订链接(测试可临时使用占位链接)。

修正后的代码:

var client = new MailjetClient(apiKey, secretKey)
{
    Version = ApiVersion.V3_1
};

var request = new MailjetRequest
{
    Resource = SendV31.Resource,
}
.Property(SendV31.FromEmail, "mymail@mydomain.com")
.Property(SendV31.FromName, "Mailjet Pilot")
.Property(SendV31.Subject, "Your Email Flight Plan")
.Property(SendV31.TextPart, "Dear passenger, welcome to Mailjet!")
.Property(SendV31.HtmlPart, "<h3>Dear passenger, welcome to Mailjet!</h3>")
.Property(SendV31.Recipients, new JArray
{
    new JObject { { "Email", "your-verified-recipient@example.com" }, { "Name", "Passenger 1" } }
})
// 营销邮件必须添加退订链接(正式环境需使用真实链接)
.Property(SendV31.Unsubscribe, new JObject 
{ 
    { "Method", "link" }, 
    { "Url", "https://yourdomain.com/unsubscribe" } 
});

var response = await client.PostAsync(request);

if (response.IsSuccessStatusCode)
{
    var data = response.GetData();
    Console.WriteLine($"Total: {response.GetTotal()}, Count: {response.GetCount()}");
    Console.WriteLine($"消息ID: {data[0]["Messages"][0]["To"][0]["MessageID"]}");
}
else
{
    Console.WriteLine($"状态码: {response.StatusCode}");
    Console.WriteLine($"错误详情: {response.GetErrorInfo()}");
    Console.WriteLine($"错误消息: {response.GetErrorMessage()}");
    Console.WriteLine($"响应数据: {response.GetData()}");
}

三、获取更多排查信息

  1. 查看Mailjet API日志
    在Mailjet后台的「账户 > API密钥 > API日志」中,可查看所有API请求的详细参数、响应状态和错误原因,这是排查问题最直接的方式。
  2. 使用Mailjet内置测试工具
    在Mailjet后台的「邮件 > 发送测试邮件」中直接发送测试邮件,若工具发送失败,说明是平台配置问题;若成功,则是代码问题。
  3. 打印完整响应数据
    不要仅打印response对象,需输出response.GetErrorInfo()、response.GetErrorMessage()和response.GetData()的完整内容,这些会包含Mailjet返回的具体错误代码和原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 09:50:11