注册时 Outlook WebAddin 抛出内部服务器错误 Office.EventType.ItemChanged

Outlook WebAddin throwing internal server error when registering Office.EventType.ItemChanged

在我的 outlook WebAddin 中,我正在尝试使用以下代码注册邮件 ItemChange 事件。

    Office.context.mailbox.addHandlerAsync(Office.EventType.ItemChanged, mailItemSelectionChanged, [], function (result) {
            if(result && result.status != 'succeeded'){
                console.error('result => ' + result);
             }
});

每当用户在固定模式下更改邮件时,我都会第一次收到邮件更改事件。然后如果对话发生变化,我将使用 location.reload() 重新加载插件以清除缓存并加载新插件。

重新加载插件后,无法注册 mailItemChange 事件并抛出以下错误:

{"code": 5001, "message": "An internal error has occurred.", "name": "Internal Error"}

它在浏览器和一些 windows 机器(在许多其他情况下工作)中失败。

outlookDiagnostics

{"host": "Outlook", "platform": "OfficeOnline", "version": "16.0.9215.1000"}

关于 Office.EventType.ItemChanged 事件注册,我可以找出以下行为:

  1. 您不能注册多个事件处理程序。大多数人在第二次尝试注册事件处理程序时遇到错误,以至于第一个事件处理程序未被取消注册。
  2. 事件处理程序的注册在加载项网页的生命周期之后继续存在。这意味着当您的加载项卸载当前网页并重新加载相同或不同的网页(即它导航到另一个网页)时,您的事件处理程序的注册仍将保留。
  3. 在注销事件处理程序时,您不仅必须提供处理程序函数的名称,而且还要确保该函数与您用来注册事件的函数完全相同。换句话说,如果您在重新加载网页后尝试取消注册事件处理程序,则处理程序函数的对象不相同,因此事件处理程序不会取消注册。
  4. 当 Outlook 关闭加载项窗格时,事件处理程序注册丢失。

因此,在您的情况下,您需要在调用 location.reload() 之前取消注册事件,如下所示。

Office.context.mailbox.removeHandlerAsync(Office.EventType.ItemChanged, {handler: mailItemSelectionChanged}, function(result) {
    if (result.status === Office.AsyncResultStatus.Failed) {
        console.log('Item Change event could not be unregistered.');
        console.log(result.error);
    }
    else {
        console.log('Item Change event unregistered successfully.');
    }
});
setTimeout(function() {location.reload();}, 100);

那些想要从他们的加载项导航到同一个或另一个网页的人,他们可以将点击事件处理程序附加到锚标记(或按钮)以确保之前取消注册 ItemChanged 事件处理程序当前页面已卸载。我使用以下代码完成了此操作:

$(document).ready(function() {
    $('.NavBarContainer a').toArray().forEach(function(anchor1, index) {
        $(anchor1).click(function(event) {
            if(itemChangeEventRegistered) {
                unregisterItemChangeHandler();
                setTimeout(function() {window.location = anchor1.href;}, 100);
                return false;
            }
            return true;
        });
    });
});