Pieter van der Westhuizen

Office 365 – Exchange Online examples

2012 is upon us and here’s wishing you all a very happy and prosperous new year! Last year we’ve taken a quick look at What Exchange Online extensibility is and what you can use it for, and in today’s post we’ll take a bit more of a hands-on approach and look at some examples of performing various tasks in Exchange Online using the Exchange Web Services API.

Let’s jump straight into some code by creating a new console application in Visual Studio 2010:

Creating a new SharePoint Ribbon project in Visual Studio 2010

Add a reference to Microsoft.Exchange.WebServices.dll, you’ll find it the C:\Program Files\Microsoft\Exchange\Web Services\1.1 folder. If you do not have the Microsoft.Exchange.WebServices dll, you probably do not have the Exchange Web Services Managed API installed. You can download it from the Microsoft Download Center.

Connecting to the Exchange Service

Before you can perform any task or run any queries against Exchange Online, you need to connect to the Exchange Online service. To do this you use the ExchangeService object.

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
service.Credentials = new WebCredentials("user@domain.com", "UserPassword");
service.AutodiscoverUrl("user@domain.com", RedirectionUrlValidationCallback);

Although the AutodiscoverUrl method has a constructor that only takes the user’s e-mail address; it will always throw an exception if the validateRedirectionUrlCallback parameter is not specified. The RedirectionUrlValidationCallback method should verify that the redirection address is valid and as a best practise, should never return true unconditionally.

static bool RedirectionUrlValidationCallback(String redirectionUrl)
{
    bool redirectionValidated = false;
    if (redirectionUrl.Equals(
		"https://autodiscover-s.outlook.com/autodiscover/autodiscover.xml"))
        redirectionValidated = true;
 
    return redirectionValidated;
}

Creating a contact

With the serviced code in place, we can now create a contact with the following code:

// Create the Contact
Contact newContact = new Contact(service);
newContact.GivenName = "John";
newContact.Surname = "Smith";
newContact.FileAsMapping = FileAsMapping.GivenNameSpaceSurname;
newContact.CompanyName = "Smith & Smith Inc.";
newContact.JobTitle = "CEO";
newContact.AssistantName = "Pocahontas";
newContact.Body = "Captain John Smith (c. January 1580 – 21 June 1631) Admiral " +
"of New England was an English soldier, explorer, and author. He was knighted " +
"for his services to Sigismund Bathory, Prince of Transylvania and friend Mozes Szekely.";
// Add E-mail Addresses
EmailAddress contactEmail1 = new EmailAddress("Work", "johnS@s-and-s.com");
EmailAddress contactEmail2 = new EmailAddress("Home", "john@gmail.com");
newContact.EmailAddresses[EmailAddressKey.EmailAddress1] = contactEmail1;
newContact.EmailAddresses[EmailAddressKey.EmailAddress2] = contactEmail2;
//Add Contact Photo
FileAttachment contactPhoto =
	newContact.Attachments.AddFileAttachment(@"C:\Temp\JohnSmith.png");
contactPhoto.IsContactPhoto = true;
//Add Extended Property
Guid propertySetId = new Guid("{F4FD924D-5489-4AE1-BD43-25491342529B}");
ExtendedPropertyDefinition clientIdPropertyDefinition =
	new ExtendedPropertyDefinition(propertySetId, "ClientId", MapiPropertyType.String);
newContact.SetExtendedProperty(clientIdPropertyDefinition, "SMITHINC");
 
newContact.Save();

The code will seem familiar if you worked with the Outlook Object model before. However, there are a number of differences: in the first part of the method, we set the standard Exchange properties. We then add 2 e-mail addresses to the contact; each e-mail address can have a descriptive name.

Next, an image is added to the contact as a file attachment. Setting the IsContactPhoto property to true will set the attached file as the contact’s picture. Finally, we add an extended property to the contact. A GUID is declared as the propertySetId, this only needs to be declared once and should be reused when accessing the extended property. You can define one property set identifier and use it for all the extended properties that get read or written to throughout your application.

When you run this code you should see the new contact in the Outlook Web app:

New contact in the Outlook Web app

If you need to create a new contact in Outlook, see this post How to create a new Outlook Contact item programmatically.

Finding contacts by name

To search for a contact in Exchange Online use the following code:

static void FindContactsByGivenName()
{
    string search = "John";
    FindItemsResults<Item> foundItems = 
        service.FindItems(WellKnownFolderName.Contacts, 
			new SearchFilter.IsEqualTo(ContactSchema.GivenName, search),
			new ItemView(5));
 
    foreach (Item item in foundItems)
    {
        if (item is Contact)
        {
            Contact foundContact = (Contact)item;
            Console.WriteLine(String.Format("{0} - {1}", 
                foundContact.CompleteName.FullName, 
                foundContact.CompanyName));
        }
    }
}

In the above code, we created a new FindItemResults collection and set it equal to the return value of the services’ FindItems method. The FindItems method accepts three parameters:

  • the first is an enumeration value specifying which folder to search;
  • the second is a new instance of a SearchFilter object, where we specify on what criteria we want to search; and
  • lastly we pass in a new instance of an ItemView object where we set the number of records to return. We then loop through the foundItems collection and print the contact details.

Finding contacts by Extended property

You can also search for an item based on the values in an extended property:

static void FindContactByExtendedProperty()
{
    string search = "SMITHINC";
    ExtendedPropertyDefinition clientIdPropertyDefinition =
        new ExtendedPropertyDefinition(propertySetId, "ClientId", 
            MapiPropertyType.String);
 
    FindItemsResults<Item> foundItems =
        service.FindItems(WellKnownFolderName.Contacts,
			new SearchFilter.IsEqualTo(clientIdPropertyDefinition, search), 
			new ItemView(5));
 
    foreach (Item item in foundItems)
    {
        if (item is Contact)
        {
            Contact foundContact = (Contact)item;
            Console.WriteLine(String.Format("{0} - {1}",
                foundContact.CompleteName.FullName,
                foundContact.CompanyName));
        }
    }
 
}

The above code is similar to searching for a contact by name except that we first declare a reference to the extended property we’ve created earlier. You’ll notice we’re reusing the Property Set Id which was declared earlier. We then pass the clientIdPropertyDefinition as a parameter for the SearchFilter. The result is a list of all contacts whose ClientId extended property has a value of "SMITHINC"

Updating contacts

Update the contact with the following code:

static void UpdateContact(string email = "johnS@s-and-s.com")
{
    FindItemsResults<Item> foundItems =
            service.FindItems(WellKnownFolderName.Contacts,
				new SearchFilter.IsEqualTo(ContactSchema.EmailAddress1, email), 
				new ItemView(5));
 
    Item foundItem = foundItems.FirstOrDefault();
    if (foundItem != null && foundItem is Contact)
    {
        Contact foundContact = (Contact)foundItem;
        foundContact.JobTitle = "Chief Operating Officer";
        foundContact.Update(ConflictResolutionMode.AutoResolve);
    }           
}

The code above first searches for a contact by e-mail address, if the contact is found we set the JobTitle property and call the Update method on the Contact object. The Update method accepts an enumeration parameter ConflictResolutionMode. Possible values for the parameter are:

  • ConflictResolution.AlwaysOverwrite – Any local property changes will overwrite any server-side changes.
  • ConflictResolution.AutoResolve – Unless the server-side copy is more recent than the local copy, its values will be overwritten by any local property changes.
  • ConflictResolution.NeverOverwrite – All local property changes are discarded.

If you compiled the code and ran it again, you would be able to see that John Smith’s Job Title has changed.

John Smith's Job Title has changed

Creating and sending an e-mail message

Creating and sending an e-mail is also similar to the Outlook object model:

static void CreateAndSendEmail()
{
    EmailMessage email = new EmailMessage(service);
    email.ToRecipients.Add(new EmailAddress(userEmail));
    email.Subject = "Sending from EWS";
    email.Body = "Hi There, this was sent using Exchange Web Services. Pretty neat!";
 
    email.Attachments.AddFileAttachment(@"C:\Temp\JohnSmith.png");
    email.SendAndSaveCopy();
}

In the code above, we created a new e-mail message and added an EmailAddress object to its ToRecipients collection. Adding an attachment is done in a similar fashion as with the contact previously. When you want to send the e-mail you have a choice between two methods on the EmailMessage object: Send or SendAndSaveCopy. The SendAndSaveCopy method sends the e-mail and saves a copy of it to the Sent Items folder. The Send method sends the e-mail and does not store a copy of it.

Once your e-mail is sent, you should see it in your Office 365 Outlook Inbox.

Once your e-mail is sent, you will see it in your Office 365 Outlook Inbox

If you need to create and send an e-mail in Outlook, see this post How to create and send an Outlook message programmatically.

Finding e-mails by subject

Finding email is similar to searching for contacts:

static void FindEmailBySubject(string subject = "Sending from EWS")
{
    FindItemsResults<Item> foundItems =
        service.FindItems(WellKnownFolderName.Inbox,
			new SearchFilter.IsEqualTo(EmailMessageSchema.Subject, subject),
			new ItemView(5));
 
    foreach (Item item in foundItems)
    {
        if (item is EmailMessage)
        {
            EmailMessage foundEmail = (EmailMessage)item;
            Console.WriteLine("From Address: " + foundEmail.From.Name);
            Console.WriteLine("Received: " +
				foundEmail.DateTimeReceived.ToShortDateString());
            Console.WriteLine("----------------------------");
        }
    }
}

The only difference between this code and searching for contacts is the WellKnowFolderName and the SearchFilter‘s parameter.

For an Outlook sample, see How to use Find and FindNext methods to retrieve Outlook mail items.

Creating appointments

To create an appointment in the default calendar use the following code:

static void CreateAppointment()
{
    Appointment app = new Appointment(service);
    app.Subject = "Meet George";
    app.Body = "You need to meet George";
    app.Location = "1st Floor Boardroom";
    app.Start = DateTime.Now.AddHours(2);
    app.End = DateTime.Now.AddHours(3);
    app.IsReminderSet = true;
    app.ReminderMinutesBeforeStart = 15;
    app.RequiredAttendees.Add(new Attendee(userEmail));
    app.Save(SendInvitationsMode.SendToAllAndSaveCopy);
}

This code creates an appointment in the default calendar and sends a meeting request to the logged-in user. The Save method accepts the SendInvitationsMode enumeration as parameter and possible values for this are:

  • SendInvitationsMode.SendOnlyToAll – Sends meeting invitations to all attendees, but does not save a copy of the meeting invitation in the organizer’s Sent Items folder.
  • SendInvitationsMode.SendToAllAndSaveCopy – Will send the meeting invitation to all attendees and save a copy of it in the organizer’s Sent Items folder.
  • SendInvitationsMode.SendToNone – Will not send any meeting invitations.

Once created you should see the meeting in your Office 365 Outlook Calendar.

The newly created meeting in your Office 365 Outlook Calendar

If you develop for Outlook, see How to create a new Outlook Appointment item.

Find appointments for today and tomorrow

To find any appointments for today and tomorrow you can use the following code:

static void FindAppointmentsForTodayTomorrow()
{
    FindItemsResults<Appointment> foundAppointments =
        service.FindAppointments(WellKnownFolderName.Calendar,
			new CalendarView(DateTime.Now, DateTime.Now.AddDays(1)));
 
    foreach (Appointment app in foundAppointments)
    {
        Console.WriteLine("Subject: " + app.Subject);
        Console.WriteLine("Start: " + app.Start);
        Console.WriteLine("Duration: " + app.Duration);
        Console.WriteLine("------------------------");
    }
}

The code is similar to finding e-mails or contacts, except the FindItemsResults collection contains an Appointment object and we used the FindAppointments method of the ExchangeService object to find the appointments. The filter is applied using a CalendarView object.

Creating folders

Creating folders in Exchange online can easily be done using the code below:

static void CreateFolder()
{
    Folder readLaterFolder = new Folder(service);
    readLaterFolder.DisplayName = "Read Later";
    readLaterFolder.Save(WellKnownFolderName.Inbox);
 
    Folder workEmailFolder = new Folder(service);
    workEmailFolder.DisplayName = "Work mail";
    workEmailFolder.Save(readLaterFolder.Id);
}

You can create a folder by declaring a new Folder object and setting its DisplayName property. The Save methods required the parent folder to be specified, you can pass in a WellKnownFolderName enumeration value or an existing folders’ Id.

You will notice two new folders in your Office 365 Outlook:

Two new folders in your Office 365 Outlook

List Inbox sub-folders

To list the sub-folders in the Inbox use the following code:

static void ListFoldersInInbox()
{
    FindFoldersResults findResults = service.FindFolders(WellKnownFolderName.Inbox,
		new FolderView(10));
 
    foreach (Folder folder in findResults.Folders)
    {
        Console.WriteLine(folder.DisplayName);
    }
}

In the code above we declare a FindFoldersResults object and set it equal to the return value of the FindFolders method on the ExchangeService object. The FindFolders method accepts either a WellKnownFolderName enumeration value or the Id of an existing folder.

Out of office

Exchange web services allow you not only to create and edit Exchange items but also to leverage its business logic. For example the following code will enable the specified user’s Out of office message:

static void SetOutOfOffice()
{
    OofSettings settings = new OofSettings();
    settings.State=OofState.Enabled;
    settings.InternalReply = new OofReply(
		"Hi Team Member, I'm out on my 2 day break. Back Soon!");
    settings.ExternalReply = new OofReply(
		"Dear Customer, I'm currently out of the office. " +
		"Please forward all queries to Sam at sam@s-and-s.com");
    settings.ExternalAudience = OofExternalAudience.Known;
    service.SetUserOofSettings(userEmail,settings);
}

By setting the State property you either enable or disable the Out of Office notification, setting it to Scheduled and specifying the Duration allow you to schedule the Out of Office notification for a later date. You also have the choice to specify different messages for internal or external addresses as well as which audience to send the response to.

You can not only set the user’s Out of Office status but can also get another user’s Out of Office status by using the following code:

static void GetOutOfOffice()
{  
    OofSettings settings = service.GetUserOofSettings(userEmail);
    if (settings.State == OofState.Enabled)
    {
        Console.WriteLine("You are currently OUT of the office");
    }
    else if (settings.State == OofState.Scheduled)
    {
        Console.WriteLine("You are currently OUT of the office and will return on " +
			settings.Duration.EndTime.ToLongDateString());
    }
    else
    {
        Console.WriteLine("You are currently IN the office");
    }       
}

Availability

You can also check a users’ availability using the EWS API. In the following example I used the GetUserAvailability method of the ExchangeService object to get an AttendeeAvailability object

static void GetAvailability()
{
    List<AttendeeInfo> attendees = new List<AttendeeInfo>();
    attendees.Add(new AttendeeInfo(userEmail));
 
    GetUserAvailabilityResults results =
		service.GetUserAvailability(attendees, 
			new TimeWindow(DateTime.Now, DateTime.Now.AddHours(24)),
			AvailabilityData.FreeBusy);
 
    AttendeeAvailability myAvailablity =
		results.AttendeesAvailability.FirstOrDefault();
    if (myAvailablity != null)
    {                
        Console.WriteLine(String.Format(
			"You have {0} appointments/meetings in the next 24 hours",
            myAvailablity.CalendarEvents.Count));
    }
}

There you have it, a crash course in some of the functionality available to you as developer when using Exchange Web services with Office 365. Please see the attached sample project for the code to all the above examples.

Thank you for reading. Until next time, keep coding!

Available downloads:

C# sample project

You may also be interested in:

65 Comments

  • Frigon says:

    Pieter – Thanks for the demo but i continue to get a 401 – Unauthorized message when i attempt any operation after authenticating. I’m on Office 365 exchange. Any ideas?

  • Pieter van der Westhuizen says:

    Hi Frigon,

    Mmm…make sure you’re username and password is correct and that the RedirectionUrlValidationCallback method returns true. You can test EWS autodiscovery using this website https://www.testexchangeconnectivity.com/

    Hope this helps.

    Thanks for your comment!

  • La Rouse says:

    Great Article. Is there a way to change the view to list view on the calendar. I am talking about where you get calendar items for 2 days. I will have it for 5 days. AddDays(4). Let me know.

    Thanks
    La Rouse

  • Pieter van der Westhuizen says:

    Hi La Rouse,

    As far as I know, there are only 4 views available for the Web version of the Outlook calendar (Day, Work Week, Week and Month) and you’re not able to add your own on the Office 365 version of hosted Outlook.

    Is this what you wanted to know?

  • amit says:

    We are getting err “The Auto Discover service could not be located”.

  • Pieter van der Westhuizen says:

    Hi Amit,

    Where are you getting this error? You can test your EWS connectivity with the help of this site https://www.testexchangeconnectivity.com/

    Kind regards,
    Pieter

  • preetam says:

    hi,

    Ihanks for such simple and helpful article.
    It helps me a lot.
    I want to know, how can we work with the mail attachment ? i am facing one situation where i want to retrieve a mail which contains an attachment with specified neme or text in it ! please suggest suitable way to do same.

    Thanks once again.


    Preetam

  • Pieter van der Westhuizen says:

    Hi Preetam,

    Sounds like an interesting challenge. I would suggest you look at the Attachments property on the EmailMessage class. Each attachment object has a load method, which you can use to save the file to a stream or to a local file. You can read more on Msdn https://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.fileattachment.load%28v=exchg.80%29.aspx

    Good luck, and thank you for your comment!

    Kind regards,
    Pieter

  • preetam says:

    Hi,

    Thanks for your suggestion.
    Will try it and update you soon, so that it might be helpful for others also.

    Thanks once again.


    Preetam

  • hans says:

    I keep getting this exception when sending an email in message.SendAndSaveCopy();

    System.InvalidOperationException: This operation can’t be performed because this service object doesn’t have an Id.

    Cannot find any cause or reason so perhaps you have an idea? This is both online and with a local Exchange server.

    Windows 7 x64 Pro
    Application 32 bit, using a .NET DLL which calls Exchange
    Microsoft Exchange Webservice DLL, 32 bit, Tried 1.1 and 1.2.

    Funny thing is that this used to work before upgrade to Office 365.

    var service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
    service.Credentials = new WebCredentials(fromName, fromPassword);
    service.Url = new Uri(“https://xxx/ews/exchange.asmx”);
    var message = new EmailMessage(service);

    message.SendAndSaveCopy();

  • Pieter van der Westhuizen says:

    Hi Hans,

    Mmm…only thing I can think of is that your Office 365 Url might be wrong.
    Do you get the same error when you AutoDiscover the Url instead of setting it manually?

    Kind regards,
    Pieter

  • Priya says:

    I am getting following error:

    The type or namespace name ‘Exchange’ does not exist in the namespace ‘Microsoft’ (are you missing an assembly reference?)

    Excuse me for very basic question, I have the Microsoft.exchange.webserviced.dll referenced in my project, still I am getting this error. What am I missing?

  • Pieter van der Westhuizen says:

    Hi Priya,

    Make sure you have the latest version of the Exchange Web Services Managed API installed (https://www.microsoft.com/en-us/download/details.aspx?id=28952) and that your projects’ Target framework is either .Net Framework 4 or .Net Framework 3.5

    Thanks for your comment!

  • Mari says:

    Hello!

    Exchange Web Services is very slow. Incoming list loaded about 4 minutes. What is the reason?

  • Pieter van der Westhuizen says:

    Hi Mari,

    This sounds lit a tough one to diagnose. I have found that things can take much longer when auto discovering the Exchange url using the AutodiscoverUrl method. Try setting the Url property on the ExchangeService object manually and try again.

    Good luck and thanks for your comment.

  • gray says:

    we are using the office365 mailbox with adfs ,kindly assist the code to connect to the mail box

  • Pieter van der Westhuizen says:

    Hi There,

    If you’re using Active Directory, you would need to pass in your AD username, password and domain instead of your Office365 username and password. e.g:

    Instead of:

    service.Credentials = new WebCredentials(“user@domain.com”, “UserPassword”);

    You’ll use System.Net.NetworkCredentials, like so:

    ExchangeService.Credentials = new System.Net.NetworkCredential(ADUsername, ADPassword, Domain);

    Hope this helps and thank you for your comment!

  • gray says:

    Thanks for your reply.

    I have tried the above code .Now the error is ‘The Autodiscover service couldn’t be located’.

    please help me in resolveing the issue.

  • Pieter van der Westhuizen says:

    Hi gray,

    Yes, that will happen.You can still use the AutodiscoverUrl method on the ExchangeService object. If that doesn’t work, you would need to manually specify the Url for the ExchangeService e.g:
    ExchangeService.Url = new Uri(“https://yourexchangeUrl”);

    You can use https://www.testexchangeconnectivity.com/ to get your exchange url, check the log it generates carefully, you will see your exchange url; it should end with Exchange.asmx

    Hope this helps.

  • Mickey says:

    How would one go about getting a specific calendar, not just mine? My account (the once I am accessing through) is an admin.

  • Pieter van der Westhuizen says:

    Hi Mickey,

    You need to give your user ApplicationImpersonation rights. To do this, sign in to Office 365, go to Manage my Organization. Go to Roles & Auditing and double-click Discover Management. Add the ApplicationImpersonation Role and then add your user to the Members list.

    Once that is done, you still use your credentials to authenticate with EWS, BUT when you want to retrieve another user’s calendar, mails, etc. you need to set the ImpersonatedUserId property of the ExchangeService object e.g :

    ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
    service.Credentials = new WebCredentials(“YourUserName”, “YourPassword”);
    service.AutodiscoverUrl(“YourUserName”, RedirectionUrlValidationCallback);
    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, “usertoimpersonate@yourcompany.com”);

    After this line:

    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, “usertoimpersonate@yourcompany.com”);

    You can retrieve data from Exchange using EWS as you would normally.

    Hope this helps!

    All the best,
    Pieter

  • Mickey says:

    Thank you. Well written article, easy to follow.

  • Mickey says:

    Worked great, thanks! One last question…any “best-practice” for setup and use in a web app, specifically for performance? Right not, takes about 8-10 seconds to round trip and get on persons calendar for a 5 day spread.

  • Pieter van der Westhuizen says:

    Great! Glad I could help.

    What i do to increase performance is to only call AutoDiscoverUrl once.
    As soon as i have the Url (ExchangeService.Url property) I save it somewhere. Then next time you call the service you first check whether the Url has been saved previously, if it has I set the ExchangeService.Url property to it.
    This then removes the need to always call the AutoDiscoverUrl method – giving you a significant speed improvement.

  • Mickey says:

    Thanks!

  • Ruwan Kumara says:

    This post helps me a lot.
    Thanks for good work.

  • mak says:

    How do you if you log in to Office 365 Exchange Admin account and programatically create the Impersonation role and assign that role to the user/s?

  • Pieter van der Westhuizen says:

    Hi Mak,

    Far as I know it is not possible to assign roles using the Exchange web services. This is something that has to be done manually.

    Thanks for your comment!

  • Alexander says:

    Hi, I have a question:
    I need to get the list of users whose mailboxes the current user can access as a delegate

  • Pieter van der Westhuizen says:

    Hi Alexander,

    Unfortunately, I’m not sure, but I did do some digging around and found this link : https://social.technet.microsoft.com/Forums/en-US/4dd25eca-3bc8-40af-947d-98400f812060/get-list-of-users-for-which-the-current-user-can-act-as-a-delegate

    Hope it helps!

  • Alexander says:

    Thank you very much, this is what i’ve expected =)

  • Nikhil says:

    Hi Pieter,

    Nice and precise article. However, I have an issue that I am not able to resolve. Would be grateful if you can provide any pointers on it. We are using the EWS to send out emails. however, before sending out the emails we need to be sure that the recipient email addresses are valid and exist in the Global directory. Is there any way to ensure that an email address exists?

    After a lot of search we hit up on a method ResolveName(), but I am not sure whether this validates a contact by the email id.

  • Pieter van der Westhuizen says:

    Hi Nikhil,

    Thanks for reading! The ResolveName method might just be exactly what you are looking for.
    It first checks the user’s contact list and the the Global Address List, for the contact name.

    Hope this helps! Good luck.

  • Gagan says:

    Hi,

    I would like to filter e-mails using FindItems and Normal Search(not using AQS) in Exchange 2013 and online.

    The filtering should be based on To,Cc and Bcc fields.
    Is it possible to search emails using FindItems for the above Search fields.

    view2.PropertySet = new PropertySet(BasePropertySet.IdOnly, EmailMessageSchema.BccRecipients, EmailMessageSchema.ToRecipients, EmailMessageSchema.CcRecipients,
    EmailMessageSchema.DisplayCc, EmailMessageSchema.DisplayTo);
    foundItems = objConnect.service.FindItems( folder.Id, searchfilter, view1);

    As per the above example, this might not be possible.
    https://blogs.msdn.com/b/brijs/archive/2010/02/12/how-to-retrieve-email-address-from-the-from-and-to-field-of-mail-item-using-ews-managed-api.aspx

    Filtering based on DisplayCc and DisplayTo also doesn’t work since DisplayCc, DisplayTo doesn’t store emailaddress instead they store the name.

    Please suggest a way to filter e-mails based on to,cc and bcc fields in Normal Search.

    Regards,
    Gagan

  • Pieter van der Westhuizen says:

    Hi Gagan,

    Have a look at the Searching for items in a mailbox by using the EWS Managed API MSDN article. Instead of using the ItemSchema property definition, use the EmailMessageSchema definition when adding search filters. For example:

    List searchFilterCollection = new List();
    searchFilterCollection.Add(new SearchFilter.ContainsSubstring(EmailMessageSchema.ToRecipients, “you@email.com”));

    Hope this helps!

  • Raj says:

    Hi , Really great and helpful post.
    can you plz provide me a sample code hot to retrieve all GAL address. (Global Address List).
    I could not able to retrieve all the records from Gal . please provide me sample code, that would be really useful.

    Thanks

  • Pieter van der Westhuizen says:

    Hi Raj,

    I haven’t had the need to work with the GAL yet, but maybe give the solution mentioned in this article a try. It looks like it might solve your problem.

    Good luck!

  • Raj says:

    Hi , thanks for the reply,
    I have went through the blog which you have mentioned.
    but i would like to proceed with your method. in that sample we need to encode service reference. so can you please share me the code how to proceed with your method.?

    That would be really helpful.

    thanks

  • Pieter van der Westhuizen says:

    Hi Raj,

    I did some digging and it appears that one cannot use EWS to access the GAL. EWS is primarily to access mailbox data.
    The only method that is an exception to this rule is the ResolveName method that can also find a specific contact in the GAL.
    Other workaround that I saw was that you could access the GAL object in AD – but it does take a lot of effort.

    Good luck

  • Rakesh says:

    I want to access resource capacity property of room using Exchange Server 2013 in C#, Can someone please guide me how to do this, have read as we need to use active directory to access but didn’t get anything regarding to this.

  • Pieter van der Westhuizen says:

    Hi Rakesh,

    It would appear that it is not possible to get the room capacity using EWS. The closest thing EWS gives us with regards to rooms are the GetRoomsLists and GetRooms method.
    I’ve found two resource about using AD to get the properties for rooms. Have a look at this and this.

    Hope it helps!
    Good luck.

  • NJ Bhanushali says:

    Hello,

    All the examples are really helpful to me. I want to download emails folderwise(not specific). Folder list may contain user created folder also. Please give me idea for it.

  • NJ Bhanushali says:

    I also want to get details of all the folders and subfolders. It makes difficult in case of subfolder and they also have subfolders.

  • Pieter van der Westhuizen says:

    Hi NJ Bhanushali,

    To get all the subfolders and their folders of the inbox, you can use the FolderTraversal Enum

    So you would declare a new FindFoldersResults object like so:
    FindFoldersResults findResults = service.FindFolders(WellKnownFolderName.Inbox,new FolderView(int.MaxValue) { Traversal = FolderTraversal.Deep });

    You would then keep calling the folder.FindFolders method for each sub folder and so on e.g:

    foreach (Folder folder in findResults.Folders)
    {
    var subFolderView = new FolderView(int.MaxValue);
    subFolderView.Traversal = FolderTraversal.Deep;
    folder.FindFolders(subFolderView);
    }

    If you would like to get the emails/items in each folder, you’ll need to call the FindItems method for each folder/subfolder.

    Hope this helps!

  • Sudha says:

    Hi,

    How to check room availability in the given start time and end time? I tried with getRoomLists and getRooms, it’s returning zero.

    Thanks,
    Sudha

  • Pieter van der Westhuizen says:

    Hi Sudha,

    I’ve done some googling, it seems it can be a bit of a problem.
    Have a look at the solutions proposed here.

    Good luck!

  • NJ Bhanushali says:

    Hello,

    I want to get information about logs from Autodiscover same as Outlook Provides. I have tried but it can’t get it.

    Please suggest me way to get it.

  • Pieter van der Westhuizen says:

    Hi NJ,

    I could not find a way to see the autodiscover logs using Exchange Web services. Unless, I’m afraid it looks like it is not possible.

  • esb says:

    Hi Pieter,

    Trying to set Out of Office but can’t set StartTime – getting ‘settings.Duration’ is null (object reference not set)
    OofSettings settings = new OofSettings();
    settings.State = OofState.Scheduled;
    settings.Duration.StartTime = someFutureDate;

    What could that be? Thx

  • Pieter van der Westhuizen says:

    Hi there,

    You need to initialize the Duration property like so:

    settings.Duration=new TimeWindow(DateTime.Now,DateTime.Now.AddHours(8));

    Hope this helps! Good Luck!

  • Jay Man says:

    Hi Pieter,

    Thank you for the excellent and simple article to follow.

    I am in the middle of a project which hooks up the streaming notification to the Exchange server, that is now done. However, I would like to share/publish a user’s calendar via EWS API, and I think the code to do so is as follow:

    var service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
    var folder = Folder.Bind(service, WellKnownFolderName.Calendar);

    folder.Permission.Add(new FolderPermission(“shareCalendarUser@myorganisarion.com”, FolderPermissionLevel.Reviewer);
    folder.Update();

    Please correct me if this is wrong. What I would like to know is how do I get the published Url that is normally sent to the recipients which you normally get when sharing calendar via Outlook. I have been digging quite a bit and unable to find any information.

    It seems that I can get the shared folder information using the cmdlet: get-MailboxCalendarFolder, is there an equivalent command in the API?

    Any help would be much appreciated.

    Kind regards,
    Jay

  • Pieter van der Westhuizen says:

    Hi Jay,

    This is an interesting one. I did some research and could not find a way to get that url. It doesn’t appear to be possible. Sorry : (
    If you do however find a way, please do let us know!

  • premchand says:

    Hello Pieter,

    We want to write some custom filter for Exchange Online, so that, before the email sent to the recipient, we wanted to scan the email for some specific header and based on that send the email to that recipient.

    We wanted to write some kind of addin or some kind of mechanism how we can achieve this?

    Thanks
    Premchand

  • Andrei Smolin (Add-in Express Team) says:

    Hello Premchand,

    We are not experts in customizing Exchange Online. After a quick google search I’ve come up with this page: https://technet.microsoft.com/en-us/library/jj919238(v=exchg.150).aspx.

  • hazel says:

    can’t u help me.. what if i want to Find appointments for today but using the Active Directory credentials. i really, desperately need help. Tq so much.

  • Andrei Smolin (Add-in Express Team) says:

    Hello Hazel,

    We are not experts in customizing Exchange Online. After a quick google search I’ve come up with these pages:
    https://social.msdn.microsoft.com/Forums/exchange/en-US/440926e7-1f1c-4f1e-8f23-7971fe3867b9/get-all-appointments-from-a-resourceroom-in-exchange-online2010-with-ews?forum=exchangesvrdevelopment
    https://msdn.microsoft.com/en-us/library/office/dn495614(v=exchg.150).aspx

    If they don’t meet your requirements, I suggest that you google; my googling isn’t any better than yours.

  • Krishna says:

    Hi Team,

    Thanks for great article.

    Is there a way in EWS to get all changed items based on last sync date ?

  • Andrei Smolin (Add-in Express Team) says:

    Hello Krishna,

    Sorry, we can’t help you with EWS. This isn’t our area.

  • mohamd says:

    thanks, great work, it is helpful, I have a question about FindContactsByGivenName()

    – I have tried to display the e-mail address in this method but I cannot, I get this ” Microsoft.Exchange.WebService.Data.EmailAdressDictionary” in screen

  • Andrei Smolin (Add-in Express Team) says:

    Hello mohamd,

    We cannot help you with this issue because FindContactsByGivenName doesn’t belong to the Outlook object model.

  • Hepsi says:

    Hi,

    When i am using the same code, while setting the out of office, I am getting this error.

    Additional information: The request failed. The remote server returned an error: (401) Unauthorized.

    Please help.

  • Andrei Smolin (Add-in Express Team) says:

    Since setting Out of Office returns (401) Unauthorized, you need to talk to your administrator.

  • Uma says:

    Hi All,

    I am trying to get the calendar events(meetings) from exchange server 2010.
    Getting error as The Autodiscover service couldn’t be located.

    ExchangeService service1 = new ExchangeService(ExchangeVersion.Exchange2010);
    service1.Credentials = new WebCredentials(“uma@XXXXX.com”, “aug@123”);
    service1.TraceEnabled = true;
    service1.TraceFlags = TraceFlags.All;
    service1.Url = new Uri(“https://xxxxxx/ews/Services.asmx”);
    service1.AutodiscoverUrl(“uma@XXXXX.com”, RedirectionUrlValidationCallback);
    EmailMessage email = new EmailMessage(service1);
    email.ToRecipients.Add(“uma@XXXXXX.com”);
    email.Subject = “HelloWorld”;
    email.Body = new MessageBody(“This is the first email I’ve sent by using the
    EWS Managed API”);
    email.Send();

  • Andrei Smolin (Add-in Express Team) says:

    Hello Uma,

    We cannot help you with this issue because the ExchangeService object doesn’t belong to the desktop Outlook object model.

  • Exchange Online Connexion - ConnexionGuider says:

    […] Exchange Online Extensibility: C# code examples […]

Have any questions? Ask us right now!