c# - 如何在 Outlook 中识别特定的约会项目

标签 c# .net outlook office-interop

我们面临一个问题,即我们需要在 Outlook 中识别特定约会,即使它是重复约会。但是自从GlobalAppointmentID对于整个循环系列来说只是独一无二的,我们不知道如何。

据我所知,如果是周期性约会,则单个约会没有特定的唯一 ID。所以我们认为我们通过将 Ticks 中的 Start-Time 添加到 GlobalAppointmentID 来生成我们自己的 ID,但是我们需要/想要将这个新 ID 保存在约会对象中(因为 StartTime 可能会改变)。

我的问题:有没有办法识别特定的约会?如果没有,我如何在特定的约会中保存一个值,让每个接收者始终可以访问并且是最新的?

//编辑:更具体一点:我们有一个 outlook 插件,允许将文件上传到我们的服务器,它必须映射到特定的约会(和所有收件人)。对于正常的一次性 session ,我们只是 GlobalAppointmentID。如果它是一个定期约会,它仍然需要映射到一个特定的“ session ”。大多数情况下,此 session /约会不包含任何时间上的异常(exception)情况或其他任何情况。所以我需要在 C# 中获取这个特定的 ID。

最佳答案

这是旧的,但它仍然出现在搜索中,所以我会尝试改进答案,因为我们公司刚刚经历过这个问题。

正如德米特里所写,重复约会的出现不存在,除非并且直到它们成为异常(exception),因为用户改变了发生的事情。这也意味着他们没有独立的ID。

但是每个异常都有一个原始日期,如果它没有被更改的话,它会发生在什么时候。对于每个非异常事件,该日期只是事件的开始日期。

表示

您可以使用全局约会 ID 和原始日期的组合来获取唯一标识约会的 ID,即使它确实发生了:

    public struct AppointmentId : IEquatable<AppointmentId>
    {
        private readonly string GlobalAppointmentId;
        private readonly LocalDate? OriginalDate;

        public AppointmentId(string globalAppointmentId)
        {
            this.GlobalAppointmentId = globalAppointmentId;
            this.OriginalDate = null;
        }

        public AppointmentId(string globalAppointmentId, LocalDate originalDate)
        {
            this.GlobalAppointmentId = globalAppointmentId;
            this.OriginalDate = originalDate;
        }

        public bool Equals(AppointmentId other)
        {
            return this.GlobalAppointmentId.Equals(other.GlobalAppointmentId, StringComparison.Ordinal) &&
                this.OriginalDate == other.OriginalDate;
        }

        public override bool Equals(object obj) =>
            obj is AppointmentId other && this.Equals(other);

        public override int GetHashCode()
        {
            unchecked
            {
                int hash = 62207;
                hash += 3 * this.GlobalAppointmentId.GetHashCode();
                hash += (5 * this.OriginalDate?.GetHashCode() ?? 0);
                return hash;
            }
        }

        public override string ToString()
        {
            if (this.GlobalAppointmentId == null) return "<None>";
            if (this.OriginalDate == null)
            {
                return $"{this.GlobalAppointmentId}";
            }
            return $"{OriginalDate.Value)} / {GlobalAppointmentId}";
        }

        public static bool operator ==(AppointmentId x, AppointmentId y) => x.Equals(y);
        public static bool operator !=(AppointmentId x, AppointmentId y) => !(x == y);
    }

这里我使用了 NodaTime 中的 LocalDate 来表示没有时间分量的原始日期。

访问

可以轻松访问全局约会 ID。如前所述,并非异常(exception)的事件的原始日期只是约会开始的日期部分。

异常更麻烦,当你只有 AppointmentItem 而不是 RecurrencePatternException 对象时,因为原始日期不是直接可用的。但是您可以通过 PropertyAccessor 获取它:

        public static LocalDate GetOriginalDate(this AppointmentItem appointment)
        {
            // The original date is stored in a property called ExceptionReplaceTime but this
            // property is not exposed in the OOM so we need to use PropertyAccessor
            // See: https://learn.microsoft.com/en-us/office/client-developer/outlook/mapi/pidlidexceptionreplacetime-canonical-property
            using (var props = appointment.PropertyAccessor.AsOwnedResource())
            {
                var p = props.Resource.GetProperty("http://schemas.microsoft.com/mapi/id/{00062002-0000-0000-C000-000000000046}/82280040");
                DateTime exceptionReplaceTime = (DateTime)p;
                return props.Resource.UTCToLocalTime(exceptionReplaceTime).ToLocalDate();
            }
        }

关于c# - 如何在 Outlook 中识别特定的约会项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23380552/

相关文章:

java - .NET C# 中的 Maven 等价物

c# - MVVM 共享代码 Win8 和 WP8 以及文件访问

C#/.NET 保持命名管道打开并支持任意数量的并行连接客户端

vba - Outlook 对象库无法在版本 12 和 14 之间切换

vba - Outlook 获取 Exchange 用户图片

C#MVC : Search Grid as Partial View to enable AJAX Return?

c# - 从 IEnumerable<IEnumerable<string>> 转换为 ICollection<T>

.net - catch block 中的返回语句

c# - 获取字符串的编码

outlook - 从 Visual Studio 2017 调试 Outlook VSTO 插件不起作用 --> 调试无法从 Outlook 中删除部署