Select attachments using Exchange Web Services - c#

Sorry if my post is a duplicate one, I tried to find a solution without success.
I need to read an Office365 email folder and get the attachments contained in each mail.
I use this code
foreach (Attachment attachment in message.Attachments)
{
if (attachment is FileAttachment)
{
FileAttachment fileAttachment = attachment as FileAttachment;
// Load the attachment into a file.
// This call results in a GetAttachment call to EWS.
fileAttachment.Load("C:\\temp\\" + fileAttachment.Name);
Console.WriteLine("File attachment name: " + fileAttachment.Name);
}
else // Attachment is an item attachment.
{
ItemAttachment itemAttachment = attachment as ItemAttachment;
// Load attachment into memory and write out the subject.
// This does not save the file like it does with a file attachment.
// This call results in a GetAttachment call to EWS.
itemAttachment.Load();
Console.WriteLine("Item attachment name: " + itemAttachment.Name);
}
}
taken from here link to do this.
But together the "real" attachments sent by the sender (pdf files, xls, or images too) the code downloads all the elements contained in each mail, i.e. logos, images inside the html body, etc.
There is a way to select only the "real" attachments and to avoid downloading logos, and other html elements contained inside the body?
Thanks for your help.
Lucius

You should be able to filter based on the other property on the Fileattachment class https://learn.microsoft.com/en-us/dotnet/api/microsoft.exchange.webservices.data.fileattachment?view=exchange-ews-api
eg
if(!Attachment.IsInline)
or check the if the ContentId is null etc

Related

Download .eml file with Microsoft Graph C#

I have some problem with Microsoft Graph.I would like to download the attachments present in a specific email. I have verified that the type of object returned after this:
var attachments = graphClient.Me.Messages[msg.Id].Attachments.Request().GetAsync().Result;
foreach(var item in attachments) {
var current_attachment = graphClient.Me.Messages[msg.Id].Attachments[item.Id].Request().GetAsync().Result;
}
is an object of type Attachment.
Now, I would like to download this object (current_attachment) but I saw that the property ContentBytes isn't available.
I have tried to cast the object to FileAttachment, but it throw an exception.
Thank you.
This should be fairly straightforward. Specifically:
https://learn.microsoft.com/en-us/graph/outlook-get-mime-message
Even though Outlook does not save messages in MIME format, there are
two ways you can get an Outlook message body in MIME format:
You can append a $value segment to a get-message operation on that
message. If the message is attached to an Outlook item or group post,
you can append a $value segment to a get-attachment operation on that
item or group post. In either case, your app must have the appropriate
permissions to access the Outlook item or group post in order to apply
the get-message or get-attachment operation.
You can then save the message body content in a .EML file and attach
the file to records in business systems, such as those for CRM, ERP,
and bug tracking.
Here is an example:
https://learn.microsoft.com/en-us/graph/api/message-get?view=graph-rest-1.0&tabs=csharp
Gets the MIME content of a message in the signed-in user's mailbox.
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var stream = await graphClient.Me.Messages["4aade2547798441eab5188a7a2436bc1"].Content
.Request()
.GetAsync();
You can write "stream" to a disk file like this:
string path = #"\my\path\myfile.eml";
using(FileStream outputFileStream = new FileStream(path, FileMode.Create))
{
stream.CopyTo(outputFileStream);
}
The resulting .eml file will be the complete email, including all attachments.
You can do a similar call to get an InputStream for the ItemAttachment as you would do to get the InputStream for a Message.
See code below in java but will be similar for c#. The java API is missing the .content() option on Attachments but you can build the url and append $value instead.
URL requestUrl = graphClient.users("user#***.com").messages("*****").attachments("****").buildRequest().getRequestUrl();
InputStream is = new FileAttachmentStreamRequestBuilder(requestUrl.toString() + "/$value", graphClient, null).buildRequest().get();
// save the file
Files.copy(is, Paths.get(fileName + extension), StandardCopyOption.REPLACE_EXISTING);

How to download multiple attachments per message with MailKit?

I've looked at a lot of the other questions on stackoverflow about this, but I'm still confused.
I want to download the attachments of emails- I was successfully able to do this, but only if the email had ONE attachment; when an email has more than one attachment, it stops working.
How do I download multiple attachments per email?
Also, is there a way to determine the file extension when downloading? Currently, for example, if there is a pdf attachment, the file downloads, but with no .pdf, so windows doesn't know the file type.
The code below is from here: MailKit save Attachments. I've been basing my code off of that.
foreach (var attachment in message.Attachments)
{
using (var stream = File.Create ("fileName"))
{
if (attachment is MessagePart)
{
var part = (MessagePart) attachment;
part.Message.WriteTo (stream);
}
else
{
var part = (MimePart) attachment;
part.ContentObject.DecodeTo (stream);
}
}
}
Please help! Thanks!
The code you pasted will already save all attachments.
Look at the raw message source. Does each "attachment" that you consider to be an attachment have a header Content-Disposition: attachment? If not, that's the problem you are hitting.
You can instead use message.BodyParts and apply your own logic to determine if the part is what you would consider to be an "attachment".
Also, is there a way to determine the file extension when downloading? Currently, for example, if there is a pdf attachment, the file downloads, but with no .pdf, so windows doesn't know the file type.
Yes. You can check the file extension on the FileName property on MimePart objects.

How to get attachment in EWS?

I am trying to get attachment from exchange; I am getting file name and other details. However, I don't want to store the attachment physically; instead whenever attachment containing mail gets open; then attachment name should be shown and after clicking on it actual attachment should get retrieved. So, here I can show the option Open/Save file(a regular windows explorer window).
My question is how can I do this ? Below is code that I worked upon; But didn't find for what I am looking for.
if (blnHasAttachments && email.Attachments[0] is FileAttachment)
{
ContentID = email.Attachments[0].ContentId;
FileAttachment fileattachment = email.Attachments[0] as FileAttachment;
fileattachment.Load();
}
Any help on this appreciated !

EWS code and Email Signatures

At the moment i'm currently using using Microsoft.Exchange.WebServices.Data library to read email addresses and send to a database. However, i'm having troubles as i currently want to loop through the attachments of a single email but exclude any attachments (images) that are included in the signature of the email.
I can get the non embedded images by
if (emailMessage.HasAttachments)
{
foreach (FileAttachment fileAttachments in emailMessage.Attachments)
{
FileAttachment fileAttachment = emailMessage.Attachments[i.Attachments.IndexOf(fileAttachments)] as FileAttachment;
fileAttachment.Load();
if (!fileAttachment.IsInline)
{
}
}
}
but is there a way to get embedded images that are not included in the signature?
You have to do reverse of what is done in this example http://www.independentsoft.de/exchangewebservices/tutorial/createinlineattachment.html
Check ContentId property value on FileAttachment and check if the same value exists in the message body. These images are not part of the email signature.

C# Pdf Attachment damaged when sent to yahoo mail addresses

I'm trying to send an Email with an attached PDF file. When I send it to any other mail provider it works just fine, but when I send it to a yahoo email address, the receiver gets a damaged pdf file. The exact message it gives is:
Adobe Reader could not open 'Filename.pdf' because it is either not a supported file type or because the file has been damaged (for example, it was sent as an email attachment and wasn't correctly decoded).
Because the other email providers were working, I used the following code specifically for yahoo addresses.
if (thisItem.EmailAddress.ToUpper().Contains("YAHOO")){
ContentType contentType = new ContentType();
contentType.CharSet = Encoding.UTF8.WebName;
Attachment theFile = new Attachment(attachmentPath, contentType);
theFile.Name = theFile.Name.Replace("_","");
mm.Attachments.Add(theFile);
}
I've tried a variety of CharSets on the ContentType, hoping that would fix something, no change. I also tried different TransferEncodings on theFile, also no fix. I read somewhere that the file name could cause problems if it had special characters so I removed all the underscores in the name, all that's left is some letters and numbers. I'm not sure what else to try at this point. Any suggestions?

Categories

Resources