守护程序应用调用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




