2014-05-20 99 views
8

我有下面的代碼:EWS - 訪問所有共享日曆

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實例。不幸的是,它仍然列出了已被刪除的文件夾,並沒有列出共享日曆。

如何獲取它以列出所有共享日曆,以及如何獲取它以不包含已刪除的文件夾?

回答

13

通過共享日曆,你的意思是在Outlook中的其他日曆節點下的日曆?

Other Calendars Node

如果是這樣,這些項是存儲在普通視圖文件夾在郵箱是下NonIPMSubtree(根)NavLinks看到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; 
    } 

乾杯 格倫

+0

哇,太棒了。我現在要試一試。謝謝! – synic

+0

這很適合獲取共享日曆文件夾。但是現在,當我嘗試訪問共享日曆中的項目時,我遇到了麻煩。基本上我需要獲得空閒/忙碌狀態。我打電話給 'service.FindItems(SharedCalendaFolder.Id,iCalenderview)',我得到了「訪問被拒絕。檢查憑據並再試一次。」錯誤。但在Outlook Web應用程序中,我可以看到共享日曆事件。 – Dimuthu

+0

要訪問日曆,您至少需要讀取日曆的訪問權限我會說您目前只擁有FreeBusy權限,因此您只能在該情況下使用GerUseravarallelity操作,除非您爲帳戶的日曆文件夾分配了更多權限。 –

1

您需要指定一個searchfilter。 這是描述here,雖然我不知道哪個Schema是正確的,但我的猜測是Archieved。

所以,你會做這樣的事情:

SearchFilter searchFilter = new SearchFilter.IsEqualTo(FolderSchema.Archieved, false); 

FindFoldersResults findFolderResults = service.FindFolders(WellKnownFolderName.MsgFolderRoot,searchFilter, view); 
+0

謝謝!這解決了刪除的顯示。想知道沒有顯示的共享文件夾嗎? – synic

+0

我bellieve你不能通過使用文件夾視圖做到這一點,而是你需要定義一個FolderId與共享該文件夾的郵箱。 – CSharpie

+0

但我不知道文件夾ID。我想要一個所有共享/公共/所有文件夾的列表。 – synic

0

格倫職位是完美的,但裝訂夾提供了錯誤。但我解決了這個問題。相反,該行:

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

使用以下行的共享文件夾裝訂

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

這裏OwnerEmailAddress是業主的郵箱地址或者你可以寫ncCol [0] .Mailbox.Address如果使用格倫的代碼。