EWS API发送邮件报错:请求的Web方法不可用问题排查
我开发了一款Outlook Web加载项,使用EWS API读取邮件属性(包括MIME内容)并在Outlook外部处理数据,该功能运行正常。新增需求为点击任务窗格按钮发送草稿邮件,我使用EmailMessage.SendAndSaveCopy()方法实现,但调用时抛出ServiceResponseException,报错信息为**"The requested web method is unavailable to this caller or application"**。
我排查后得知需要在加载项清单中提升权限至最高级ReadWriteMailbox,已完成此操作,但API调用仍失败。我在拥有完整管理员权限的私有Microsoft 365开发租户中侧加载了该加载项。
我想了解:
- 我的操作是否存在错误?若有,正确的做法是什么?
- Microsoft是否已弃用EWS的Send方法,转而推动开发者使用Graph API?
加载项清单相关片段
<Hosts> <Host Name="Mailbox" /> </Hosts> <Requirements> <Sets> <Set Name="Mailbox" MinVersion="1.1" /> </Sets> </Requirements> <Permissions>ReadWriteMailbox</Permissions> <Rule xsi:type="RuleCollection" Mode="Or"> <Rule xsi:type="ItemIs" ItemType="Message" FormType="ReadOrEdit" /> </Rule> <VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides" xsi:type="VersionOverridesV1_0"> <Requirements> <bt:Sets DefaultMinVersion="1.3"> <bt:Set Name="Mailbox" /> </bt:Sets> </Requirements> <Hosts> <Host xsi:type="MailHost"> <DesktopFormFactor> <ExtensionPoint xsi:type="MessageReadCommandSurface"> <OfficeTab id="TabDefault"> <Group id="Group.MessageRead"> <Label resid="Group.Label" /> <Control xsi:type="Button" id="HomeButton.MessageRead"> <!-- ... --> </Control> </Group> </OfficeTab> </ExtensionPoint> <ExtensionPoint xsi:type="MessageComposeCommandSurface"> <OfficeTab id="TabDefault"> <Group id="Group.MessageCompose"> <Label resid="Group.Label" /> <Control xsi:type="Button" id="HomeButton.MessageCompose"> <!-- ... --> </Control> </Group> </OfficeTab> </ExtensionPoint> </DesktopFormFactor> </Host> </Hosts> </VersionOverrides>
获取邮件数据的JavaScript函数
var _getMailboxItem = function(onSuccess) { var ewsItemId = Office.context.mailbox.item.itemId; var afterSave = function() { var ewsUrl = Office.context.mailbox.ewsUrl; Office.context.mailbox.getCallbackTokenAsync({}, function(getCallbackTokenResult) { if(getCallbackTokenResult.status !== Office.AsyncResultStatus.Succeeded) { _handleOfficeError(getCallbackTokenResult, "Cannot read the mailbox item."); return; } var ewsToken = getCallbackTokenResult.value; onSuccess({ url: ewsUrl, token: ewsToken, itemId: ewsItemId }); }); }; if(ewsItemId) { // We have the item ID already, it's safe to continue. afterSave(onSuccess); } else { // We must save the item first before we can read data. console.log("Saving the item first..."); Office.context.mailbox.item.saveAsync(function(saveAsyncResult) { if(saveAsyncResult.status !== Office.AsyncResultStatus.Succeeded) { _handleOfficeError(saveAsyncResult, "Cannot save a draft of the mailbox item."); return; } ewsItemId = saveAsyncResult.value; afterSave(onSuccess); }); } };
发送草稿邮件的ASP.NET MVC 4.8控制器相关代码
private static ExchangeService GetExchangeService(MailboxItemModel mailboxItem) => new ExchangeService { Url = new Uri(mailboxItem.Url), Credentials = new OAuthCredentials(mailboxItem.Token) }; private static EmailMessage GetEmailMessage(MailboxItemModel mailboxItem) => EmailMessage.Bind( GetExchangeService(mailboxItem), mailboxItem.ItemId, new PropertySet(BasePropertySet.IdOnly) { ItemSchema.IsDraft, ItemSchema.IsUnmodified, ItemSchema.MimeContent }); private static void Send(EmailMessage emailMessage) { // Safety check: if the caller didn't pass an email message, then we can't do anything. if(emailMessage == null) { return; } // Safety check: only send if EWS confirms that the message is a draft. if(!emailMessage.IsDraft) { return; } emailMessage.SendAndSaveCopy(); }
1. 操作中的错误及修正方案
你的操作存在两处关键问题:
(1)回调令牌权限未明确指定
通过getCallbackTokenAsync获取的令牌默认仅授予读取权限,即使清单中设置了ReadWriteMailbox,也需要在调用时显式指定权限范围为ReadWrite。修改JavaScript中的调用代码:
Office.context.mailbox.getCallbackTokenAsync({isRest: false, permission: "ReadWrite"}, function(getCallbackTokenResult) { // 原有逻辑不变 });
注:isRest: false明确指定获取EWS专用令牌,避免返回REST格式令牌导致权限不匹配。
(2)EWS绑定的属性集需补充关键字段
在EmailMessage.Bind时,需确保加载足够的权限相关字段,可添加ItemSchema.WebClientReadFormQueryString或扩大属性集范围,确保令牌能获取发送操作的权限验证所需信息。
额外验证步骤
- 侧加载加载项后,重新登录Outlook Web,确保权限更新生效;
- 检查租户EWS权限策略:确认未禁用EWS API的发送操作(可通过Exchange管理中心验证);
- 验证草稿的
IsUnmodified状态:如果草稿已被外部修改,SendAndSaveCopy可能失败,可尝试先调用Update方法同步草稿内容。
2. EWS Send方法的弃用情况
Microsoft并未完全弃用EWS的Send方法,但已明确将Graph API作为未来优先开发方向:
- EWS目前处于维护模式,仅修复严重安全漏洞,不再添加新功能;
- Graph API提供更统一的跨平台接口,支持更多场景(如团队邮件、跨服务集成等),且权限控制更精细;
- 对于Outlook加载项,Microsoft推荐使用Graph API的
/me/sendMail或/messages/{id}/send端点实现发送功能,搭配加载项SSO令牌获取方式,比EWS更稳定且符合未来生态。
内容的提问来源于stack exchange,提问作者Christian Hayter

