You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

守护程序应用调用Microsoft Graph API发送邮件报错排查

问题根源分析

你遇到的BadRequest错误,核心原因是创建GraphServiceClient时传入了错误的基地址。你现在把某个具体API的路径(https://graph.microsoft.com/v1.0/0a181b4b-a2fb-4e38-b23b-2c72adc882f2/users/c26d8491-82f8-4f08-990e-35a73ad61ede/memberOf)当成了客户端的基URL,这会导致后续调用SendMail时,请求的路径完全混乱,Graph API无法识别正确的函数调用,从而抛出"Functions on open properties are not supported"的错误。

修复步骤

1. 修正GraphServiceClient的初始化方式

创建GraphServiceClient时,只需要传入Graph API的基础端点(https://graph.microsoft.com/v1.0/),不需要具体的资源路径。同时推荐直接用ClientCredentialProvider初始化客户端,无需手动获取令牌,这样更简洁且不易出错。

修改后的初始化代码:

// 直接用ClientCredentialProvider初始化GraphServiceClient,无需手动处理令牌
var graphServiceClient = new GraphServiceClient(_clientCredentialProvider);

如果坚持手动处理令牌,也需要把基地址改成正确的:

var graphServiceClient = new GraphServiceClient("https://graph.microsoft.com/v1.0/", new DelegateAuthenticationProvider(async (requestMessage) => {
    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
}));

2. 确认权限配置正确

因为你使用的是Client Credential流,需要在Azure AD应用注册中添加应用权限(而非委派权限),并且完成管理员同意。发送邮件需要的权限是Mail.Send(应用权限),请确认已经添加并完成授权。

3. 完整修正后的SendMail方法

public async Task<bool> SendMail(List<UserEntitlement> sortedListByLastAccessDate)
{
    // 正确初始化GraphServiceClient
    var graphServiceClient = new GraphServiceClient(_clientCredentialProvider);
    
    var message = new Message
    {
        Subject = "Meet for lunch?",
        Body = new ItemBody
        {
            ContentType = BodyType.Text,
            Content = "The new cafeteria is open."
        },
        ToRecipients = new List<Recipient>()
        {
            new Recipient
            {
                EmailAddress = new EmailAddress
                {
                    Address = "Bla@hotmail.com"
                }
            }
        },
        From = new Recipient
        {
            EmailAddress = new EmailAddress
            {
                Address = "bla.bla@test.nl"
            }
        }
    };
    var saveToSentItems = false;
    
    // 现在调用SendMail会生成正确的API请求路径
    await graphServiceClient.Users["c26d8491-82f8-4f08-990e-35a73ad61ede"]
        .SendMail(message, saveToSentItems)
        .Request()
        .PostAsync();
        
    return true;
}

错误原因详解

当你把memberOf的路径作为基URL时,后续调用Users[id].SendMail()会拼接出错误的请求地址:
https://graph.microsoft.com/v1.0/0a181b4b-a2fb-4e38-b23b-2c72adc882f2/users/c26d8491-82f8-4f08-990e-35a73ad61ede/memberOf/users/c26d8491-82f8-4f08-990e-35a73ad61ede/sendMail

这个路径完全不符合Graph API的规范,Graph会把users当成memberOf这个开放属性下的子资源,而sendMail作为函数调用在这种场景下是不被支持的,所以抛出了错误。

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

火山引擎 最新活动