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

使用Microsoft Graph API发送邮件遇空引用错误求助

问题排查:Microsoft Graph API发送邮件时出现“Object reference not set to an instance of an object”错误

使用Microsoft Graph API发送邮件,Message部分内容完整,但执行Task.Delay后调用发送接口时抛出“Object reference not set to an instance of an object”错误,无法定位问题。

完整代码

try
{
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

    //var url = GetMailConfig(configGroup: "EWS", configName: "EwsUrl");
    var username = GetMailConfig(configGroup: "EWS", configName: "Email");
    var password = GetMailConfig(configGroup: "EWS", configName: "Password");
    var fromAddress = GetMailConfig(configGroup: "SMTP", configName: "From");
    //var traceEnabled = GetMailConfig(configGroup: "EWS", configName: "TraceEnabled");
    var tenantId = GetMailConfig(configGroup: "EWS", configName: "TenantId");
    var clientId = GetMailConfig(configGroup: "EWS", configName: "ClientId");
    var access_token = "";
    var redirect_uri = "https://example.example.com/";
    var clienSecretId = "This is secret key";
    //var scopes = new[] { "https://outlook.office365.com/SMTP.Send" };
    var scopes = new[] {"https://graph.microsoft.com/.default" };

    var pca = ConfidentialClientApplicationBuilder
    .Create(clientId)
    .WithClientSecret(clienSecretId)
    .WithAuthority(new Uri($"https://login.microsoftonline.com/{tenantId}"))
    .Build();

    var authProvider = new DelegateAuthenticationProvider(async (request) =>
    {
        try
        {
            var result = await pca.AcquireTokenForClient(scopes).ExecuteAsync();
            request.Headers.Authorization =
                new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
        }
        catch (Exception exp)
        {
            // 吞掉了身份验证异常
        }
    });

    GraphServiceClient graphClient = new GraphServiceClient(authProvider);

    var message = new Message
    {
        Subject = mailTemplate.Subject,
        From = new Recipient() { EmailAddress = new Microsoft.Graph.EmailAddress { Address = "example@example.com" } },
        Body = new ItemBody
        {
            ContentType = Microsoft.Graph.BodyType.Html,
            Content = mailTemplate.Body
        },
    };

    MailMessage mail = new MailMessage();

    var attachments = new MessageAttachmentsCollectionPage();

    if (mailTemplate.Cc != null && mailTemplate.Cc.Any())
        message.CcRecipients = mailTemplate.Cc.Select(x => new Recipient()
        {
            EmailAddress = new Microsoft.Graph.EmailAddress
            {
                Address = x
            }
        });

    if (mailTemplate.To != null && mailTemplate.To.Any())
        message.ToRecipients = mailTemplate.To.Select(x => new Recipient()
        {
            EmailAddress = new Microsoft.Graph.EmailAddress
            {
                Address = x
            }
        });

    var saveToSentItems = false;

    System.Threading.Tasks.Task.Run(async () =>
    {
        try
        {
            await Task.Delay(TimeSpan.FromSeconds(5));
            await graphClient.Me
           .SendMail(message, saveToSentItems)
           .Request()
           .PostAsync();
        }
        catch (Exception ex)
        {
            // 吞掉了发送异常
        }
    });
}
catch (Exception exp)
{
    isSentMailSuccess = false;
}
return isSentMailSuccess;

异常发生代码段

await Task.Delay(TimeSpan.FromSeconds(5));
await graphClient.Me
.SendMail(message, saveToSentItems)
.Request()
.PostAsync();

排查关键点

  • 身份验证异常被吞:委托认证提供者内部的try/catch没有处理或记录异常,可能获取token失败导致后续请求无有效授权,引发空引用。需移除内部catch或添加日志,确认token是否正常获取。
  • graphClient.Me使用错误:当前采用客户端凭据模式(应用权限),该模式下没有用户上下文,不能使用Me指代当前用户,需替换为具体用户邮箱,例如graphClient.Users["指定用户邮箱"].SendMail(...)。
  • 收件人集合赋值问题:Select返回的是IEnumerable<Recipient>,而Message的ToRecipients/CcRecipients要求是IList<Recipient>,直接赋值可能导致序列化时出现空引用,需转换为List:message.ToRecipients = mailTemplate.To.Select(...).ToList();。
  • 异步任务未等待:外层函数直接返回isSentMailSuccess,但异步发送任务可能还未执行完成,虽不是空引用直接原因,但会导致返回结果不准确,需改为await Task.Run(...)并将外层方法标记为async。
  • 对象生命周期风险:异步任务中的graphClient、message可能被外层代码提前释放,需确保这些对象在异步执行期间始终有效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:34:57