9
votes

I'm trying to get all the meetings for a specific room, perhaps I'm going down the wrong road but so far the most promising results are produced when I impersonate the room and then get a calendar view - the problem is that for each calendar entry the Subject contains the name of the user and not the actual meeting subject. E.g. instead of the Subject data member containing 'Budget Meeting', it contains 'Bob Smith'.

Is there a better way to get a list of calendar entries for a specific room? Here is my code:

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
service.Credentials = new WebCredentials("[email protected]", "password");
service.AutodiscoverUrl("[email protected]", RedirectionUrlValidationCallback);
service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "[email protected]");

DateTime startDate = DateTime.Now;
DateTime endDate = startDate.AddDays(30);
const int NUM_APPTS = 5;

CalendarFolder calendar = CalendarFolder.Bind(service, WellKnownFolderName.Calendar, new PropertySet());
CalendarView cView = new CalendarView(startDate, endDate, NUM_APPTS);
cView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End);
FindItemsResults<Appointment> appointments = calendar.FindAppointments(cView);

foreach (Appointment a in appointments)
{
    Console.Write("Subject: " + a.Subject.ToString() + " ");
    Console.Write("Start: " + a.Start.ToString() + " ");
    Console.Write("End: " + a.End.ToString());
    Console.WriteLine();
}
2

2 Answers

4
votes

If you want to try another approach, you can get all of the appointments and then filter on location:

ExchangeServices.ExchangeService exchangeService = connectToServiceWhatever(userInfo); // have working service
var folderView = new ExchangeServices.FolderView(100);   // or something like 100, idunno
folderView.Traversal = ExchangeServices.FolderTraversal.Deep;
folderView.PropertySet = new ExchangeServices.PropertySet(ExchangeServices.FolderSchema.FolderClass,
                ExchangeServices.FolderSchema.DisplayName, ExchangeServices.FolderSchema.TotalCount,
                ExchangeServices.FolderSchema.ParentFolderId);   // ... and/or whatever else you want to get - folderclass is important though. 
ExchangeServices.FindFoldersResults folders = exchangeService.FindFolders(ExchangeServices.WellKnownFolderName.MsgFolderRoot, folderView);

Now all you need to do is filter on folder type, get all the items, and then filter on room:

var appointments = folders.Where(f => f.FolderClass == "IPF.Appointment").SelectMany(f => exchangeService.FindItems(f.Id, new ExchangeServices.ItemView(folder.TotalCount < 5 ? folder.TotalCount : 5)).Where(a => a.Location == "Boardroom");  // or whatever room you want. 

That might not be copy-pastable, since I just typed it out right now, but I hope it's enough to get the idea across. You end up doing a little more work on your end but hopefully you also end up with the ability to check for appointment.Subject, appointment.Start|End.ToUniversalTime(), etc.

Here is the working code:

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
service.Credentials = new WebCredentials("[email protected]", "password");
service.AutodiscoverUrl("[email protected]", RedirectionUrlValidationCallback);

var folderView = new FolderView(100);   // or something like 100, idunno
folderView.Traversal = FolderTraversal.Deep;
folderView.PropertySet = new PropertySet(FolderSchema.FolderClass,FolderSchema.DisplayName, FolderSchema.TotalCount,FolderSchema.ParentFolderId);   // ... and/or whatever else you want to get - folderclass is important though. 

FindFoldersResults folders = service.FindFolders(WellKnownFolderName.MsgFolderRoot, folderView);
// Process each item.
foreach (Folder myFolder in folders.Folders)
{
    if (myFolder is CalendarFolder)
    {
        var calendar = (myFolder as CalendarFolder);
        // Initialize values for the start and end times, and the number of appointments to retrieve.
        DateTime startDate = DateTime.Now;
        DateTime endDate = startDate.AddDays(30);
        const int NUM_APPTS = 15;
        // Set the start and end time and number of appointments to retrieve.
        CalendarView cView = new CalendarView(startDate, endDate, NUM_APPTS);
        // Limit the properties returned to the appointment's subject, start time, and end time.
        cView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End);
        // Retrieve a collection of appointments by using the calendar view.
        FindItemsResults<Appointment> appointments = calendar.FindAppointments(cView);
        foreach (Appointment a in appointments)
        {
            Console.Write("Subject: " + a.Subject.ToString() + " ");
            Console.Write("Start: " + a.Start.ToString() + " ");
            Console.Write("End: " + a.End.ToString());
            Console.WriteLine();
        }
    }
}
0
votes

By default Exchange replaces the Subject with the Organizer's Name when sending the appointment to the Room resource. This can be disabled via Exchange Management Console with the below command, to preserve the subject

Set-CalendarProcessing -Identity <RESOURCEMAILBOX> -DeleteSubject $False -AddOrganizerToSubject $False

Reference : https://support.microsoft.com/en-us/help/2842288/resource-mailbox-s-calendar-shows-the-organizer-s-name-instead-of-the