【问题标题】:EWS - Access All Shared CalendarsEWS - 访问所有共享日历
【发布时间】:2014-07-09 03:00:18
【问题描述】:

我有以下代码:

    private void ListCalendarFolders(ref List<EBCalendar> items, int offset)
    {
        var pageSize = 100;
        var view = new FolderView(pageSize, offset, OffsetBasePoint.Beginning);
        view.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties);
        view.PropertySet.Add(FolderSchema.DisplayName);
        view.PropertySet.Add(FolderSchema.EffectiveRights);

        view.Traversal = FolderTraversal.Deep;

        FindFoldersResults findFolderResults = service.FindFolders(WellKnownFolderName.MsgFolderRoot, view);
        foreach (Folder myFolder in findFolderResults.Folders)
        {
            if (myFolder is CalendarFolder)
            {
                var folder = myFolder as CalendarFolder;
                items.Add(EBCalendar.FromEWSFolder(folder));
            }
        }

        if (findFolderResults.MoreAvailable)
        {
            offset = offset + pageSize;
            ListCalendarFolders(ref items, offset);
        }
    }

其中serviceExchangeService 实例。不幸的是,它仍然会列出已删除的文件夹,并且不会列出共享日历。

如何让它列出所有共享日历,如何让它不包括已删除的文件夹?

【问题讨论】:

    标签: c# .net exchange-server exchangewebservices office365


    【解决方案1】:

    共享日历是指 Outlook 中其他日历节点下的日历吗?

    如果是这样,这些项目是存储在非IPMSubtree(根)下邮箱的Common Views 文件夹中的导航链接,请参阅http://msdn.microsoft.com/en-us/library/ee157359(v=exchg.80).aspx。您可以使用 EWS 从邮箱获取 NavLink,并使用 PidTagWlinkAddressBookEID 扩展属性获取这些链接所引用的邮箱的 X500 地址,然后使用解析名称将其解析为 SMTP 地址。然后您需要做的就是绑定到该文件夹​​,例如

         static Dictionary<string, Folder> GetSharedCalendarFolders(ExchangeService service, String mbMailboxname)
        {
            Dictionary<String, Folder> rtList = new System.Collections.Generic.Dictionary<string, Folder>();
    
            FolderId rfRootFolderid = new FolderId(WellKnownFolderName.Root, mbMailboxname);
            FolderView fvFolderView = new FolderView(1000);
            SearchFilter sfSearchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "Common Views");
            FindFoldersResults ffoldres = service.FindFolders(rfRootFolderid, sfSearchFilter, fvFolderView);
            if (ffoldres.Folders.Count == 1)
            {
    
                PropertySet psPropset = new PropertySet(BasePropertySet.FirstClassProperties);
                ExtendedPropertyDefinition PidTagWlinkAddressBookEID = new ExtendedPropertyDefinition(0x6854, MapiPropertyType.Binary);
                ExtendedPropertyDefinition PidTagWlinkGroupName = new ExtendedPropertyDefinition(0x6851, MapiPropertyType.String);
    
                psPropset.Add(PidTagWlinkAddressBookEID);
                ItemView iv = new ItemView(1000);
                iv.PropertySet = psPropset;
                iv.Traversal = ItemTraversal.Associated;
    
                SearchFilter cntSearch = new SearchFilter.IsEqualTo(PidTagWlinkGroupName, "Other Calendars");
                // Can also find this using PidTagWlinkType = wblSharedFolder
                FindItemsResults<Item> fiResults = ffoldres.Folders[0].FindItems(cntSearch, iv);
                foreach (Item itItem in fiResults.Items)
                {
                    try
                    {
                        object GroupName = null;
                        object WlinkAddressBookEID = null;
    
                        // This property will only be there in Outlook 2010 and beyond
                        //https://msdn.microsoft.com/en-us/library/ee220131(v=exchg.80).aspx#Appendix_A_30
                        if (itItem.TryGetProperty(PidTagWlinkAddressBookEID, out WlinkAddressBookEID))
                        {
    
                            byte[] ssStoreID = (byte[])WlinkAddressBookEID;
                            int leLegDnStart = 0;
                            // Can also extract the DN by getting the 28th(or 30th?) byte to the second to last byte 
                            //https://msdn.microsoft.com/en-us/library/ee237564(v=exchg.80).aspx
                            //https://msdn.microsoft.com/en-us/library/hh354838(v=exchg.80).aspx
                            String lnLegDN = "";
                            for (int ssArraynum = (ssStoreID.Length - 2); ssArraynum != 0; ssArraynum--)
                            {
                                if (ssStoreID[ssArraynum] == 0)
                                {
                                    leLegDnStart = ssArraynum;
                                    lnLegDN = System.Text.ASCIIEncoding.ASCII.GetString(ssStoreID, leLegDnStart + 1, (ssStoreID.Length - (leLegDnStart + 2)));
                                    ssArraynum = 1;
                                }
                            }
                            NameResolutionCollection ncCol = service.ResolveName(lnLegDN, ResolveNameSearchLocation.DirectoryOnly, false);
                            if (ncCol.Count > 0)
                            {
    
                                FolderId SharedCalendarId = new FolderId(WellKnownFolderName.Calendar, ncCol[0].Mailbox.Address);
                                Folder SharedCalendaFolder = Folder.Bind(service, SharedCalendarId);
                                rtList.Add(ncCol[0].Mailbox.Address, SharedCalendaFolder);
    
    
                            }
    
                        }
                    }
                    catch (Exception exception)
                    {
                        Console.WriteLine(exception.Message);
                    }
    
                }
            }
            return rtList;
        }
    

    干杯 格伦

    【讨论】:

    • 哇,太棒了。我现在要试一试。谢谢!
    • 这对于获取共享日历文件夹非常有用。但是现在当我尝试访问共享日历中的项目时遇到了麻烦。基本上我需要获得空闲/忙碌状态。我打电话给service.FindItems(SharedCalendaFolder.Id, iCalenderview),我得到“访问被拒绝。检查凭据并重试。”错误。但在 Outlook Web 应用程序中,我可以看到共享的日历事件。
    • 要访问日历,您至少需要对日历的读取权限我会说您目前只有 FreeBusy 权限,因此您只能在这种情况下使用 GerUseravailiblity 操作,除非您为您帐户的日历文件夹。
    • 您好,很遗憾,如果共享日历不是默认日历,这将不起作用。例如。用户 A 创建了一个名为 Public 的日历并与用户 B 共享。 TryGetProperty 在这些项目上失败,即使它适用于默认日历。
    • 是否有与此等效的 EWS XML 请求/响应?我遇到了同样的问题,但不确定如何将其转换为 XML。
    【解决方案2】:

    Glen 帖子很完美,但绑定文件夹出错。但是我解决了这个问题。而不是这一行:

    Folder SharedCalendaFolder = Folder.Bind(service, SharedCalendarId);
    

    使用以下行进行共享文件夹绑定

    CalendarFolder calendar = CalendarFolder.Bind(service, new FolderId(WellKnownFolderName.Calendar, OwnerEmailAddress), new PropertySet());
    

    这里 OwnerEmailAddress 是所有者的电子邮件地址,如果使用 Glen 的代码,您可以编写 ncCol[0].Mailbox.Address。

    【讨论】:

      【解决方案3】:

      您需要指定一个搜索过滤器。 这被描述为here,虽然我不确定哪个架构是正确的,但我的猜测会被归档。

      所以你会做这样的事情:

      SearchFilter searchFilter = new SearchFilter.IsEqualTo(FolderSchema.Archieved, false);
      
      FindFoldersResults findFolderResults = service.FindFolders(WellKnownFolderName.MsgFolderRoot,searchFilter, view);
      

      【讨论】:

      • 谢谢!这解决了已删除的显示。对未显示的共享文件夹有任何想法吗?
      • 我相信您不能通过使用文件夹视图来做到这一点,而是需要使用共享文件夹的邮箱定义一个 FolderId。
      • 但我不知道文件夹 ID。我想要一份所有共享/公共/拥有文件夹的列表。
      • 好的,尝试使用 WellKnownfolderName.PublicFoldersRoot 进行第二次 FindFolders-Call 也许枚举支持标志,因此您可以在一次 FindFoldersCall 中完成此操作
      • 先检查这个问题再回答stackoverflow.com/questions/13877629/…
      猜你喜欢
      • 2011-05-12
      • 1970-01-01
      • 1970-01-01
      • 2017-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多