First, you need to generate EWS 2007 proxy. In Visual Studio it is relatively easy: Project->Add service reference, enter the address of your exchange web server, for example, https://mail.microsoft.com/EWS/Exchange.asmx (you won't be able to use this one because it is obviously secured). Hit Go, then name the namespace and hit OK.
One problem with EWS 2007 is that it unfortunately requires user credentials - cleartext (they are sent using HTTPS, so the wire security is not a problem, but the user has to enter the password/user name, or the software needs to CryptProtectData the credentials and store them. Windows auth is not available.
See here for a snippet of code that stores the password SECURELY: http://1-800-magic.blogspot.com/2008/11/encrypting-data-in-net.html. Make sure you're running under real user account (not LocalService, and definitely not NetworkSerivce), otherwise anybody will be able to decrypt the password.
Once the proxy has been generated, and put in the namespace, and the namespace has been included in the file with "using" directive, we can start coding.
First, we need to bind to the service. Binding is required for all examples below:
const string EXCHANGE_URL = @"https://mail.mydomain.com/EWS/Exchange.asmx";Looking up a subfolder of inbox:
ExchangeServiceBinding binding = new ExchangeServiceBinding();
binding.Credentials = new NetworkCredential(User, Password, Domain);
binding.Url = EXCHANGE_URL;
DistinguishedFolderIdType inbox = new DistinguishedFolderIdType();Here's how to get all email (we're only getting the ids of messages, the contents needs to be queried using a different request, covered later:
inbox.Id = DistinguishedFolderIdNameType.inbox;
BaseFolderIdType[] parentFolder = new BaseFolderIdType[1];
parentFolder[0] = inbox;
FindFolderType folderRequest = new FindFolderType();
folderRequest.FolderShape = new FolderResponseShapeType();
folderRequest.FolderShape.BaseShape = DefaultShapeNamesType.AllProperties;
folderRequest.Traversal = FolderQueryTraversalType.Shallow;
folderRequest.ParentFolderIds = parentFolder;
FindFolderResponseType folderResponse = binding.FindFolder(folderRequest);
foreach (ResponseMessageType responseMessage in folderResponse.ResponseMessages.Items)
{
FindFolderResponseMessageType findFolderResponseMessage =
responseMessage as FindFolderResponseMessageType;
if (findFolderResponseMessage.ResponseClass == ResponseClassType.Success)
{
BaseFolderType[] folders = findFolderResponseMessage.RootFolder.Folders;
foreach (BaseFolderType folder in folders)
{
if (folder.DisplayName.Equals(folderWeAreLookingFor))
{
...do stuff
}
}
}
}
Now, suppose we accumulated all message ids that we want to get in the items list, (we presume that items.Count() > 0). We will now get all the messages as follows:
DistinguishedFolderIdType inbox = new DistinguishedFolderIdType();
inbox.Id = DistinguishedFolderIdNameType.inbox;
BaseFolderIdType[] parentFolder = new BaseFolderIdType[1];
parentFolder[0] = inbox;
FindItemType listRequest = new FindItemType();
listRequest.ItemShape = new ItemResponseShapeType();
listRequest.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;
listRequest.Traversal = ItemQueryTraversalType.Shallow;
listRequest.ParentFolderIds = parentFolder;
FindItemResponseType listResponse = binding.FindItem(listRequest);
Listitems = new List ();
foreach (ResponseMessageType responseMessage in listResponse.ResponseMessages.Items)
{
FindItemResponseMessageType findItemResponseMessage =
responseMessage as FindItemResponseMessageType;
if (findItemResponseMessage.ResponseClass == ResponseClassType.Success)
{
ArrayOfRealItemsType realItems =
findItemResponseMessage.RootFolder.Item as ArrayOfRealItemsType;
if (realItems != null && realItems.Items != null)
{
foreach (ItemType item in realItems.Items)
{
if (item is MessageType)
{
MessageType message = item as MessageType;
items.Add(message.ItemId);
}
}
}
}
}
GetItemType getRequest = new GetItemType();Suppose we want to move a message to a different folder. We need to find folder's id (see above for how to enumerate folders). If we do have this id, and the id of the message we're trying to move:
getRequest.ItemShape = new ItemResponseShapeType();
getRequest.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;
getRequest.ItemIds = items.ToArray();
SnippetsDataContext snippets = new SnippetsDataContext(Database);
GetItemResponseType getResponse = binding.GetItem(getRequest);
foreach (ResponseMessageType responseMessage in getResponse.ResponseMessages.Items)
{
ItemInfoResponseMessageType getItemResponseMessage =
responseMessage as ItemInfoResponseMessageType;
if (getItemResponseMessage.ResponseClass == ResponseClassType.Success)
{
ArrayOfRealItemsType realItems =
getItemResponseMessage.Items as ArrayOfRealItemsType;
if (realItems != null && realItems.Items != null)
{
foreach (ItemType item in realItems.Items)
{
if (item is MessageType)
{
MessageType message = item as MessageType;
// Message now contains everything, except for attachments.
...
}
}
}
}
}
Ok, enough moving stuff around. Let's send something!
MoveItemType moveRequest = new MoveItemType();
moveRequest.ToFolderId = new TargetFolderIdType();
moveRequest.ToFolderId.Item = targetFolder;
moveRequest.ItemIds = new BaseItemIdType[1];
moveRequest.ItemIds[0] = messageId;
MoveItemResponseType moveResponse = binding.MoveItem(moveRequest);
Many messages can be acted upon (moved, sent, deleted) by one command - all it takes is putting multiple messages or ids in Items.Items array.
ExchangeServiceBinding binding = new ExchangeServiceBinding();
binding.Credentials = new NetworkCredential(User, Password, Domain);
binding.Url = EXCHANGE_URL;
DistinguishedFolderIdType folder = new DistinguishedFolderIdType();
folder.Id = DistinguishedFolderIdNameType.sentitems;
TargetFolderIdType targetFolder = new TargetFolderIdType();
targetFolder.Item = folder;
CreateItemType createItem = new CreateItemType();
createItem.MessageDisposition = MessageDispositionType.SendAndSaveCopy;
createItem.MessageDispositionSpecified = true;
createItem.SavedItemFolderId = targetFolder;
MessageType message = new MessageType();
EmailAddressType recipient = new EmailAddressType();
recipient.EmailAddress = "email@domain.com";
message.ToRecipients = new EmailAddressType[1];
message.ToRecipients[0] = recipient;
message.Subject = "Hello, World!";
message.Sensitivity = SensitivityChoicesType.Normal;
message.Body = new BodyType();
message.Body.BodyType1 = BodyTypeType.Text;
message.Body.Value = "This is my first automated email!";
createItem.Items = new NonEmptyArrayOfAllItemsType();
createItem.Items.Items = new MessageType[1];
createItem.Items.Items[0] = message;
binding.CreateItem(createItem);
Dealing with the web service is A LOT of code - even with the help of the proxy. Comare this to the Office interop, where most of the above tasks take 10-15 lines of code. http://1-800-magic.blogspot.com/2008/11/fun-with-outlook-and-net.html
More on EWS 2007 here: http://msdn.microsoft.com/en-us/library/bb418726.aspx
1 comment:
At work with outlook usually I use easy passwords,but once I used difficult and forget it.In this situation for myself helped next tool-outlook 2000 pst recover password.It myself advised familiar.As he said it is free and can also recover forgotten or lost passwords for email accounts as well as for files with *.pst extension.
Post a Comment