HOWTO: EWS: Use GetAttachment to download attachments off Mail/Appointment
I have fallen for exchange web services. There are endless possibilities with exchange web services, and product group is still working to make it even better.
Today I have created a neat sample to download attachments off Exchange Server
Sample: DownloadAttachments
Input Params: itemID , folder
public void DownloadAttachments(string itemID,string folder)
{
ExchangeServiceBinding esb = new ExchangeServiceBinding();
esb.AllowAutoRedirect = true;
esb.Credentials = new System.Net.NetworkCredential("USERNAME", "PASSWORD", "DOMAIN");
esb.Url = "https://your-cas-server/ews/exchange.asmx";
//first we need to get the attachment IDs for the item so we will need to make a GetItem call first
//specify the conetent that we want to retrieve
PathToUnindexedFieldType[] ptufta = new PathToUnindexedFieldType[2];
ptufta[0] = new PathToUnindexedFieldType();
ptufta[0].FieldURI = UnindexedFieldURIType.itemAttachments;
ptufta[1] = new PathToUnindexedFieldType();
ptufta[1].FieldURI = UnindexedFieldURIType.itemHasAttachments;
ItemResponseShapeType irst = new ItemResponseShapeType();
irst.BaseShape = DefaultShapeNamesType.IdOnly;
irst.AdditionalProperties = ptufta;
ItemIdType[] biita = new ItemIdType[1];
biita[0] = new ItemIdType();
biita[0].Id = itemID;
//get the items
GetItemType git = new GetItemType();
git.ItemShape = irst;
git.ItemIds = biita;
GetItemResponseType girt = esb.GetItem(git);
if (girt.ResponseMessages.Items[0].ResponseClass != ResponseClassType.Success)
return;
//now that we have the attachment IDs let's request the atthacments and save them to disk
ItemType MsgItem = ((ItemInfoResponseMessageType)girt.ResponseMessages.Items[0]).Items.Items[0];
AttachmentResponseShapeType arst = null;
AttachmentIdType[] aita = null;
if (true == MsgItem.HasAttachments)
{
//create the attachment shape; we want the mime contnet just in case this is an message item so that we can save to disk
arst = new AttachmentResponseShapeType();
arst.IncludeMimeContent = true;
arst.IncludeMimeContentSpecified = true;
//create an array of attachment ids that we want to request
aita = new AttachmentIdType[MsgItem.Attachments.Length];
for (int i = 0; i < MsgItem.Attachments.Length; i++)
{
aita[i] = new AttachmentIdType();
aita[i].Id = MsgItem.Attachments[i].AttachmentId.Id;
}
}
//create a GetAttachment object for the GetAttachment operation
GetAttachmentType gat = new GetAttachmentType();
gat.AttachmentIds = aita;
gat.AttachmentShape = arst;
GetAttachmentResponseType gart = esb.GetAttachment(gat);
//save each attachment to disk
foreach (AttachmentInfoResponseMessageType Attachment in gart.ResponseMessages.Items)
{
switch (Attachment.Attachments[0].GetType().Name)
{
//attachments can be of type FileAttachmentType or ItemAttachmentType
//so we need to figure out which type we have before we manipulate it
case "FileAttachmentType":
//save to disk
FileAttachmentType TheFileAttachment = (FileAttachmentType)Attachment.Attachments[0];
using (Stream FileToDisk = new FileStream(folder + @"\" + Attachment.Attachments[0].Name, FileMode.Create))
{
FileToDisk.Write(TheFileAttachment.Content, 0,
TheFileAttachment.Content.Length);
FileToDisk.Flush();
FileToDisk.Close();
}
break;
case "ItemAttachmentType":
//save to disk
ItemType TheItemAttachment = ((ItemAttachmentType)Attachment.Attachments[0]).Item;
using (Stream FileToDisk = new FileStream(folder + @".\" + Attachment.Attachments[0].Name + ".eml", FileMode.Create))
{
byte[] ContentBytes = System.Convert.FromBase64String(TheItemAttachment.MimeContent.Value);
FileToDisk.Write(ContentBytes, 0,
ContentBytes.Length);
FileToDisk.Flush();
FileToDisk.Close();
}
break;
default:
break;
}
}
}
Keywords: GetAttachment, download attachments, exchange web services, exchange 2007
Comments
Anonymous
November 04, 2007
thanks for your article..... That's what i wantAnonymous
January 22, 2008
The comment has been removedAnonymous
January 29, 2008
How can I get the from-email-address? The GetItemResponse include following tags, but I can't find getter methods for that: <Sender> <Mailbox> <Name>Name</Name> <EmailAddress>name@test.com</EmailAddress> <RoutingType>SMTP</RoutingType> </Mailbox> </Sender> ... <From> <Mailbox> <Name>Name</Name> <EmailAddress>Name@test.com</EmailAddress> <RoutingType>SMTP</RoutingType> </Mailbox>Anonymous
June 04, 2008
Great article... How are you obtaining the itemID that you are passing in. I've tried numerous ID's that I'm getting from the message which all return a malformedID response code.Anonymous
June 09, 2008
The itemId is unique Base64 encoded string value, which represents a unique item in store. You can use FindItem to find a particular item in store and then call GetItem on the ItemID returned by that FindItem call. Refer to the following post which has sample code for GetFolder, FindItem, GetItem and how to use restrictions with FindItem http://blogs.msdn.com/vikas/archive/2007/07/27/howto-getfolder-finditem-restriction-getitem.aspxAnonymous
December 11, 2008
Friends, I am new to the world of exchange server 2007, can anyone suggest me that how can I proceede to fetch mailbox details (Subject / has attachments, if yes attachment details..) Thanks.Anonymous
March 17, 2009
This was EXACTLY what I needed! Thank You A Million!! You are a genius!Anonymous
April 20, 2009
This code works great unless there's a inline image (i.e. signature logo). But how can I detect if it's an inline image or not. The book inside Microsoft Exchange Server 2007 Web Services says that Exchange Web Services doesn't provide a way to determine the visibility of an attachment. What's the right way to handle this so we can get all attachments?Anonymous
June 10, 2009
Just had to say thank you. Wish I found this page 4 hours ago!!Anonymous
June 11, 2009
I always get following error when i try to use this method: "The request failed with HTTP status 403: Forbidden" Do you know if I'm doing something wrong or passing through the wrong ID? I tried with *DownloadAttachments(mt.Attachments[0].AttachmentId.Id, @"c:temp"); *DownloadAttachments(it.ItemId.Id, @"c:temp"); But always the same errorAnonymous
June 16, 2009
The comment has been removedAnonymous
August 19, 2009
Great! Had the information I was after. Thanks!Anonymous
November 28, 2012
Download Attachment link is not working..Anonymous
April 13, 2014
Hi, I am using EWS with SearchFilterCollection, and the Inbox I am checking should have 4 emails that are in scope, 3 with 0, 1, or multiple file attachments, and 1 with an item attachment. My trouble is that when I apply my searchfilter (> searchFilterCollection.Add(new SearchFilter.IsEqualTo(EmailMessageSchema.HasAttachments, true)); <) I don't get the one with the email <Item> attachment Is there a special searchFilter for this?Anonymous
April 14, 2014
The comment has been removedAnonymous
July 31, 2014
Hi Vikas, This was a great help. Unfotunetaly the item I am testing with is a valid .msg attachment which you can open and read the email, but the TheItemAttachment.MimeContent is null. All the other properties are populated (body, subject, from etc). Any ideas how I can get this ItemType to be saved to disc then, since its MimeContent is null?Anonymous
December 10, 2015
unable to save attachments exchange server 2007 sp1 using c#. // logged on to the domain. service.Credentials = new WebCredentials(AppConfigSettings.EmailAccountName, AppConfigSettings.Password, AppConfigSettings.ExchangeDomain); service.Url = new Uri(AppConfigSettings.ExchangeWebServiceLink); ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; // FindItems(); FindItemsResults<Item> findResults = service.FindItems( WellKnownFolderName.Inbox, new ItemView(30000)); foreach (Item item in findResults.Items) { item.Load(); if (item.HasAttachments) { foreach (var i in item.Attachments) { FileAttachment fileAttachment = (FileAttachment)item.Attachments[0]; fileAttachment.Load("C:\temp" + fileAttachment.Name); } } getting exception as "The request failed. Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."