EWS - Access All Shared Calendars
Solution 1
By Shared Calendars do you mean the calendars under the other calendars node in Outlook ?
If so these Items are NavLinks that are stored in the Common Views folder in a Mailbox which is under the NonIPMSubtree (root) see http://msdn.microsoft.com/en-us/library/ee157359(v=exchg.80).aspx. You can use EWS to get the NavLinks from a Mailbox and use the PidTagWlinkAddressBookEID extended property to get the X500 address of the Mailbox these Links refer to and then use Resolve Name to resolve that to a SMTP Address. Then all you need to do is Bind to that folder eg
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;
}
Cheers Glen
Solution 2
You need to specify a searchfilter. this is described here, though im not sure which Schema is the correct one, my guess would be Archieved.
So you would do something like this:
SearchFilter searchFilter = new SearchFilter.IsEqualTo(FolderSchema.Archieved, false);
FindFoldersResults findFolderResults = service.FindFolders(WellKnownFolderName.MsgFolderRoot,searchFilter, view);
Solution 3
Glen post is perfect but binding folder gives error. However i solved this. Instead of this line:
Folder SharedCalendaFolder = Folder.Bind(service, SharedCalendarId);
use the following line for shared folder binding
CalendarFolder calendar = CalendarFolder.Bind(service, new FolderId(WellKnownFolderName.Calendar, OwnerEmailAddress), new PropertySet());
Here OwnerEmailAddress is Email Address of Owner or you can write ncCol[0].Mailbox.Address if using Glen's code.
synic
Updated on June 04, 2022Comments
-
synic almost 2 years
I've got the following code:
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); } }
Where
service
is anExchangeService
instance. Unfortunately, it still lists folders that have been deleted, and it doesn't list shared calendars.How can I get it to list all the shared calendars, and how can I get it to not include the folders that have been deleted?
-
synic almost 10 yearsThanks! This solves the deleted ones showing. Have any idea about the shared folders not showing up?
-
CSharpie almost 10 yearsI bellieve you cant do this by using a folder view, instead you need to define a FolderId with the mailbox that is sharing the folder.
-
synic almost 10 yearsBut I don't know the folder ID. I'd like a list of all shared/public/owned folders.
-
CSharpie almost 10 yearsOk try with a second FindFolders-Call using WellKnownfolderName.PublicFoldersRoot Maybe the enum supports flags so you might be able to do it in one FindFoldersCall
-
CSharpie almost 10 yearsCheck this questions first Answer aswell stackoverflow.com/questions/13877629/…
-
synic almost 10 yearsWow, that's awesome. I'm going to give it a try right now. Thank you!
-
Lee Harrison over 9 yearsI don't seem to have access to the FolderSchema.Archived property. Any ideas? I'm returning all deleted items as well and its not very useful.
-
Dimuthu about 8 yearsThis works great to obtain shared calendar folders. But now I am having trouble when I try to access the items in shared calendars. Basically I need to get the free/busy state. I was calling
service.FindItems(SharedCalendaFolder.Id, iCalenderview)
and I got "Access is denied. Check credentials and try again." error. But in outlook web app I am able to see shared calendar events. -
Glen Scales about 8 yearsTo Access a Calendar you will need at least Read Access to the calendar I would say you only have FreeBusy rights at the moment so you can only use the GerUseravailiblity operation in that case unless you assign more rights to the calendar folder for your account.
-
KirilStankov over 4 yearsHi, unfortunately, this doesn't work if the shared calendar is not the default Calendar. E.g. user A created a calendar called Public and shared it with user B. The TryGetProperty fails on these items, even though it works with default calendars.
-
strangetimes over 4 yearsIs there a EWS XML request / response equivalent of this? I'm having the same issue, but not sure how to translate this into XML.