Click here to Skip to main content
Click here to Skip to main content

Programming With Exchange Server 2007 (EWS) - Part 1

By , 28 Aug 2008
 

Introduction

Recently I worked on a custom MailClient project. In that, we used EWS API provided by Exchange Server 2007 which is fairly new. During development, we faced many problems. On the Internet, you will get a lot of results but they are really scattered and some of them are missing. Here I want to share my knowledge with all of you and try to provide all the required information and sample code in this series. In every part, I'll take one functionality and try to explore that. Any suggestion will be highly appreciated.

What Is Exchange Server?

Exchange Server is a messaging system that includes Mail Server, e-mail client and GroupWare application. Exchange Server is generally used with Microsoft Outlook and tightly integrated with Active Directory and Instant Messenger.

Messaging System comprises creation, storage, maintenance of different kinds of messages like email, voice mail, fax, images, etc.

Exchange Server API's History

exchange11.JPG

What is Exchange Web Services

EWS (Exchange Web Services) is an Application Programming Interface which can be used by different developers to communicate with Microsoft Exchange Server 2007.

This API is exposed as SOAP (Simple object Access Protocol)- based Web-service, which means a requester must send their request in an XML form using SOAP to EWS contained in an HTTP POST request. EWS itself responds in the same manner using SOAP and XML messages in the HTTP response object. EWS is exposed on a Exchange Client Access Server (CAS) through an ASP.NET 2.0 Web service. This can be represented pictorially as follows:

Exchange22.JPG
Client talking SOAP + XML to EWS

Special Features

  • Efficient access to Outlook PIM objects
  • Notifications and events
  • Synchronization
  • Availability service
  • Autodiscover service
  • E-mail Lifecycle
  • OWA WebParts

How to Use EWS

Most Web services publish a “Contract” of sorts that tell those on the outside what the service can do and how to communicate with it. EWS exposes this contract as a standard Web Services Description Languages (WSDL) document named services.wsdl which resides in the same directory as Web service. One can look into it.

To use it “Add a Web Reference to your project”. It may ask you to supply your credentials, so go ahead if prompted.

Note: Certificate Issues - depending on the nature of the certificate that the Exchange CAS provides to Visual Studio, It might complain that the certificate is untrusted and disable the Add Reference button, so you need to install this certificate.

Now you are ready to use the EWS in your application.

Here, I will take one method exposed by EWS and try to explore it.

Using the Code

How to Send a Mail - Normal Mail

The sample code is like this:

public void SendMessage(
string subject,
string body,
string toEmailAddress)
{
 // Set the version, credentials, and the Client Access server on ExchangeServiceBinding.
    ExchangeServiceBinding esb = new ExchangeServiceBinding();
    esb.Credentials = new NetworkCredential("user2", "password", "domain");
    esb.Url = "https://www.example.com/ews/exchange.asmx";

// Create a CreateItem request object
CreateItemType request = new CreateItemType();

// Setup the request:
// Indicate that we only want to send the message. No copy will be saved.
request.MessageDisposition = MessageDispositionType.SendOnly;
request.MessageDispositionSpecified = true;

// Create a message object and set its properties
MessageType message = new MessageType();
message.Subject = subject;
message.Body = new BodyType();
message.Body.BodyType1 = BodyTypeType.Text;
message.Body.Value = body;
message.ToRecipients = new EmailAddressType[1];
message.ToRecipients[0] = new EmailAddressType();
message.ToRecipients[0].EmailAddress = toEmailAddress;
message.ToRecipients[0].RoutingType = "SMTP"; 

//There are some more properties in MessageType object 
//you can set all according to your requirement
// Construct the array of items to send
request.Items = new NonEmptyArrayOfAllItemsType();
request.Items.Items = new ItemType[1];
request.Items.Items[0] = message;

// Call the CreateItem EWS method.
CreateItemResponseType response = esb.CreateItem(request);
this.ThrowOnError("SendMessage", response.ResponseMessages.Items[0]);
}

How to Send a Mail with Attachment

To send mail with attachment:

  1. Create a MessageType object using CreateItem
  2. Add the attachments using CreateItem
  3. Send the message using SendItem

Creating a messageType Object using CreateItem

public ItemIdType CreateMessage(
string subject,
string body,
string toEmailAddress)
{
 // Set the version, credentials, and the Client Access server on ExchangeServiceBinding.
    ExchangeServiceBinding esb = new ExchangeServiceBinding();
    esb.Credentials = new NetworkCredential("user2", "password", "domain");
    esb.Url = https://www.example.com/ews/exchange.asmx;

// Create a CreateItem request object
CreateItemType request = new CreateItemType();

// Setup the request:
// Indicate that we only want to send the message. No copy will be saved.
request.MessageDisposition = MessageDispositionType.SaveOnly;
request.MessageDispositionSpecified = true;

// Create a message object and set its properties
MessageType message = new MessageType();
message.Subject = subject;
message.Body = new BodyType();
message.Body.BodyType1 = BodyTypeType.Text;
message.Body.Value = body;

message.ToRecipients = new EmailAddressType[1];
message.ToRecipients[0] = new EmailAddressType();
message.ToRecipients[0].EmailAddress = toEmailAddress;
message.ToRecipients[0].RoutingType = "SMTP";

//Note: Same you can set CC and BCC Recipients

// Construct the array of items to send
request.Items = new NonEmptyArrayOfAllItemsType();
request.Items.Items = new ItemType[1];
request.Items.Items[0] = message;

// Call the CreateItem EWS method.
CreateItemResponseType response = esb.CreateItem(request);
this.ThrowOnError("SendMessage", response.ResponseMessages.Items[0]);
}   

Adding the Attachments

public ItemIdType CreateAttachment(string name,string FilePath, ItemIdType p_signalId)
{
 ExchangeServiceBinding esb = new ExchangeServiceBinding();
    esb.Credentials = new NetworkCredential("user2", "password", "domain");
    esb.Url = "https://www.example.com/ews/exchange.asmx";

FileAttachmentType fileAttachment = null;

//Create add attachment request.
CreateAttachmentType attachementRequest = new CreateAttachmentType();

attachementRequest.ParentItemId = p_signalId;
attachementRequest.Attachments = new AttachmentType[intAttachmentsCount];

fileAttachment = new FileAttachmentType();
MessageBDO.AttachmentsDTRow drowAttachment
= (MessageBDO.AttachmentsDTRow)p_signal.AttachmentsDT.Rows[intIndex];

fileAttachment.Name =name;
fileAttachment.ContentType = "text/plain";
fileAttachment.Content = System.IO.File.ReadAllBytes(FilePath);
attachementRequest.Attachments[intIndex] = fileAttachment;

ItemIdType attachmentItemId = new ItemIdType();
CreateAttachmentResponseType response = 
	(CreateAttachmentResponseType)_esb.CreateAttachment(attachementRequest );
if (response.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Success)
{
AttachmentIdType attachmentId = ((AttachmentInfoResponseMessageType)
	response.ResponseMessages.Items[0]).Attachments[0].AttachmentId;
attachmentItemId.ChangeKey = attachmentId.RootItemChangeKey.ToString();
attachmentItemId.Id = attachmentId.RootItemId.ToString();
}
return attachmentItemId;
}

Now Sending the Mail

 //Here the itemID is returned by the CreateMessage Function         
public bool SendMessage(ItemIdType p_itemId)
 {
 bool blnResult = false;
 SendItemType siSendItem = new SendItemType();
 siSendItem.ItemIds = new BaseItemIdType[1];
 siSendItem.SavedItemFolderId = new TargetFolderIdType();
 DistinguishedFolderIdType siSentItemsFolder = new DistinguishedFolderIdType();
 siSentItemsFolder.Id = DistinguishedFolderIdNameType.sentitems;
 siSendItem.SavedItemFolderId.Item = siSentItemsFolder;
 siSendItem.SaveItemToFolder = true;
 
 siSendItem.ItemIds[0] = (BaseItemIdType)p_itemId;
 SendItemResponseType srSendItemResponseMessage = _esb.SendItem(siSendItem);
 if (srSendItemResponseMessage.ResponseMessages.Items[0].ResponseClass == 
	ResponseClassType.Success)
 {
 blnResult = true;
 }
 else
 {
 blnResult = false;
 }
 return blnResult;
 }  

Reference

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Brij
Software Developer (Senior)
India India
Member
Brij is a Microsoft MVP in ASP.NET/IIS Category and a passionate .NET developer. Having around 5 years of experience in IT field, currently serving a MNC as a Sr. developer.
 
He is a very passionate .NET developer and have expertise over Web technologies like ASP.NET 2.0/3.5/4.0, jQuery, JSON, Javascript, IIS and related technologies. He is also a Exchange Server (EWS) Specialist. He has great experience in design patterns and N-Tier Architecture.
 
He is also certified as Microsoft Certified Technologies Specialist-ASP.NET and Microsoft Certified Technologies Specialist-WCF in .NET 4.0. He has also received several awards at various forums and his various articles got listed as "Article of the day" at ASP.NET Microsoft Official Website www.asp.net.
 
He has done MCA from NIT Durgapur and completed his graduation from Lucknow University.
 
Learning new technologies and sharing knowledge excites him most. Blogging, solving problems at various forums, helping people, keeps him busy entire day.


Visit his Blog: Brij's arena of .NET
 
Area of Expertise :
C#, ASP.NET 2.0,3.5,4.0, AJAX, JQuery, JSON, XML, XSLT, ADO.Net, WCF, Active Directory, Exchange Server 2007 (EWS), Java script, Web Services ,Win services, DotnetNuke, WSS 3.0,Sharepoint Designer, SQL Server 2000/2005/2008

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionCreate email with set up DateTimeCreated [modified]memberИван Старцев15 May '13 - 0:11 
Hi. I write client application that uses Exchange Web Services Proxy Classes in order to connect to Exchange Web Services. Sometimes, I need create MessageType object and make it looks like as received letter. Therefore I need set up such properties of EmailMessage as ReceiveBy, DateTimeCreate, DateTimeReceived, but they haven’t public set assessTherefore I need set up such properties of EmailMessage as ReceiveBy, DateTimeCreate, DateTimeReceived, but they haven’t public set assessor.
Is there any way to set up such properties with Proxy Classes?
 
I found resolve, but there uses Maneged API
http://ireznykov.wordpress.com/2013/03/09/set-property-of-emailmessage-in-ews/
 
I tried to use extended properties:
ItemType newItem = xmlParser.LoadItem(); //info for newItem takes from xml
            newItem.ExtendedProperty = new ExtendedPropertyType[1];
            PathToExtendedFieldType q = new PathToExtendedFieldType();
            q.PropertyId = 3590; //DeliveryTime ID
            q.PropertyType = MapiPropertyTypeType.SystemTime;
            q.PropertyIdSpecified = true;
            newItem.ExtendedProperty[0] = new ExtendedPropertyType();
            newItem.ExtendedProperty[0].ExtendedFieldURI = q;
            newItem.ExtendedProperty[0].ExtendedFieldURI.DistinguishedPropertySetIdSpecified = true;
            newItem.ExtendedProperty[0].Item = new System.DateTime(2014, 5, 5, 5, 5, 5).ToString("yyyy-MM-ddTHH:mm:ssZ");
 
            // Create an object of create item type
            CreateItemType createItemType = new CreateItemType();
...
 CreateItemResponseType createItemResponse = m_mailbox.CreateItem(createItemType);
It works, but i don`t see any changes.
 
I tried to update items, but this properties can`t be chanded in such way.
//Update created item
                ItemIdType itemId = new ItemIdType();
                itemId.Id = savedMessageId;
                itemId.ChangeKey = savedMessageChangeKey;
 
                ItemType setCreateDT = new ItemType();
 
                setCreateDT.DateTimeCreated = new System.DateTime(2000, 10, 10, 12, 12, 12);
                setCreateDT.DateTimeCreatedSpecified = true;
 
                SetItemFieldType setItemField = new SetItemFieldType();
                setItemField.Item = new PathToUnindexedFieldType();
                (setItemField.Item as PathToUnindexedFieldType).FieldURI = UnindexedFieldURIType.itemDateTimeCreated;
                setItemField.Item1 = setCreateDT;
 
                UpdateItemType request = new UpdateItemType();
                request.ItemChanges = new ItemChangeType[1] { new ItemChangeType() };
                request.ItemChanges[0].Item = itemId;
                request.ItemChanges[0].Updates = new ItemChangeDescriptionType[1];
                request.ItemChanges[0].Updates[0] = setItemField;
                request.MessageDisposition = MessageDispositionType.SaveOnly;
                request.MessageDispositionSpecified = true;
 
                UpdateItemResponseType updateItemResponse = m_mailbox.UpdateItem(request);
This request returns error.

modified 15 May '13 - 7:27.

AnswerRe: Create email with set up DateTimeCreatedmemberИван Старцев20 May '13 - 1:28 
Well, i found answer. I have a mistake in my code.
ItemType newItem = xmlParser.LoadItem(); //info for newItem takes from xml
            newItem.ExtendedProperty = new ExtendedPropertyType[1];
            PathToExtendedFieldType q = new PathToExtendedFieldType();
            q.PropertyTag = "57"; //DeliveryTime
            q.PropertyType = MapiPropertyTypeType.SystemTime;
            newItem.ExtendedProperty[0] = new ExtendedPropertyType();
            newItem.ExtendedProperty[0].ExtendedFieldURI = q;
            newItem.ExtendedProperty[0].Item = new System.DateTime(2014, 5, 5, 5, 5, 5).ToString("yyyy-MM-ddTHH:mm:ssZ");
 
            // Create an object of create item type
            CreateItemType createItemType = new CreateItemType();
...
 CreateItemResponseType createItemResponse = m_mailbox.CreateItem(createItemType);
 
This works FINE. I tried to setup to many parametrs for PathToExtendedFieldType. There must be only "Tag" and "Type".
QuestionSigned E-mails with PFX certificated and EWSmemberfetcher14 May '13 - 3:29 
Hello,
 
How can I send a signed e-mail using EWS(preferably EWSMAPI)? I've looked everywhere but I can't find a single example.
 

Something like this:
An S/MIME Library for Sending Signed and Encrypted E-mail[^]
 
Thank you
QuestionThe request failed with HTTP status 401: Unauthorized.memberSarvesh Kushwaha23 Jan '13 - 2:10 
i have added a web refernce of Exchange web service and given my credentials. i m able to work with this on localhost ,
 
while i am running it on server or to any other machine , its giving me an error - "The request failed with HTTP status 401: Unauthorized."
 
things i have tried but did'nt worked -
 
1.enable anonymous authenication
 
2.given folder permission
 
3.   used service.UseDefaultCredentials = true;
 
please help me out , if there is any other way i can try .
GeneralMy vote of 2memberVEMS4 Oct '12 - 9:51 
too little info
Questionsending mail with attachment without save ismemberMember 905482731 May '12 - 21:34 
In the part that explanes sending mail with attachment, there is a mistake in the comment section:
 
// Indicate that we only want to send the message. No copy will be saved.
request.MessageDisposition = MessageDispositionType.SaveOnly;
request.MessageDispositionSpecified = true;  
it actualy saves the copy. What I want to do is sending mail with attachment without saving it to sentitems (or any other) folder. Is it possible?
 
Using EWS API 1.2 it can be done, so I guess it should work here also.
 
If I set (si=SendItemType):
si.SaveItemToFolder = False
and leave SavedItemFolderId empty (as documented in msdn), the message stays in Drafts folder.
 
What to do?
QuestionSynching Of Contacts to a Private DatabasememberSachin Dubey4 Apr '12 - 22:14 
Dear All,
 
I have an application which have users as contacts.
 
Users are just customers who buy from my web application.
 
I want to synch user database with Microsoft Exchange Contacts.
Mean i need synching between them..
 
Please advise how i go about it..
 
Many Thanks
GeneralMy vote of 1memberJosep Maria Roy15 Dec '11 - 20:57 
This code does not work for EWS 1.1. Please update
GeneralChanging From Name in Codemembersupremeben18 Oct '10 - 6:13 
Hello;
How can send email from contact@domain.com and Name will be "Jhon Smith" or "Marry Smith". In orher words how can I display different for from Name.
 
Thank you!!
GeneralRe: Changing From Name in CodementorBrij18 Oct '10 - 9:41 
supremeben wrote:
How can send email from contact@domain.com and Name will be "Jhon Smith" or "Marry Smith".

 
Every email is associated to a single Name. If you want different name, you should update the Name property, then use it.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 29 Aug 2008
Article Copyright 2008 by Brij
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid