Access the email attachment - c#

I am trying to access the file attachment in the email message and upload the attachment to a azure table storage as a blob.
using Microsoft.Exchange.WebServices.Data
public void SendEmail(EmailMessage emailMessage)
{Stream stream = null;
foreach (Attachment attachment in emailMessage.Attachments)
{
if (attachment is FileAttachment)
{
FileAttachment file = (FileAttachment)attachment;
file.Load(stream);
emailAttachment.UploadEmailAttachment(attachmentFileName, stream);// This will upload to the table storage
}
}
}
when I load the attachment I am getting a error saying "The request failed schema validation: The required attribute 'Id' is missing.".
Any idea regarding this

As I understand, all you are looking for a way to load the contents of the attachment into a stream which you can further upload as blob.
If that is the case, I would suggest you to write the contents of your file attachment into MemoryStream instead:
var stream = new System.IO.MemoryStream(fileAttachment.Content);
If you want to read the contents as string, you can do that as well:
var reader = new System.IO.StreamReader(stream, UTF8Encoding.UTF8);
var text = reader.ReadToEnd();
Hope this helps!

Related

How to properly remove an attachment from an email using Aspose.Email

In my application users can upload emails to a file server, these emails should then be stripped of their attachments and converted into a PDF to be saved individually. But I'm having problems correctly removing the attachments from the email.
When I'm converting an email and saving it with its attachments it works perfectly, but when I remove the attachments first and then save it, it somehow corrupts the generated PDF file making it look like this (this is just one of 4 pages generated from a 4 line email). Can anyone explain what I'm doing wrong?
This is my code to remove the attachments from the email:
public static List<(string FileName, Stream Content)> GetEmailAndAttachmentsFromEmail(Stream emailContent)
{
var email = MailMessage.Load(emailContent);
var retval = new List<(string, Stream)>
{
($"{email.Subject}.msg", emailContent)
};
var attachmentsToRemove = new List<Attachment>();
foreach (var attachment in email.Attachments)
{
retval.Add((attachment.Name, attachment.ContentStream));
attachmentsToRemove.Add(attachment);
}
foreach (var attachment in attachmentsToRemove)
{
email.Attachments.Remove(attachment);
}
return retval;
}
I've already tried multiple permutations of this code, but none worked.
Also, I'm following the official Aspose documentation on this subject and I don't see what I'm doing differently/ wrong.
It turns out I did something funky with my streams and I had to save my email without the attachments before returning it, here is my revised code:
public static List<(string FileName, Stream Content)> GetEmailAndAttachmentsFromEmail(Stream emailContent)
{
var email = MailMessage.Load(emailContent);
// I removed the prepending of the email here and moved it to the end
var retval = new List<(string, Stream)>();
var attachmentsToRemove = new List<Attachment>();
foreach (var attachment in email.Attachments)
{
retval.Add((attachment.Name, attachment.ContentStream));
attachmentsToRemove.Add(attachment);
}
foreach (var attachment in attachmentsToRemove)
{
email.Attachments.Remove(attachment);
}
// This part is new
var newEmailContent = new MemoryStream();
email.Save(newEmailContent);
newEmailContent.Seek(0, SeekOrigin.Begin);
retval = retval.Prepend(($"{email.Subject}.msg", newEmailContent)).ToList();
return retval;
}
It now works like a charm

Microsoft Graph - Saving file attachments through C#?

Is it possible to save file attachments in C# through Microsoft Graph API?
I know I can get the properties of the attachment (https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/attachment_get) - can we also save it to a certain location?
Once you have particular Microsoft Graph message, you can e.g. pass it to a method as parameter. Then you need to make another request to get attachments by message Id, iterate through attachments and cast it to FileAttachment to get access to the ContentBytes property and finally save this byte array to the file.
private static async Task SaveAttachments(Message message)
{
var attachments =
await _client.Me.MailFolders.Inbox.Messages[message.Id].Attachments.Request().GetAsync();
foreach (var attachment in attachments.CurrentPage)
{
if (attachment.GetType() == typeof(FileAttachment))
{
var item = (FileAttachment)attachment; // Cast from Attachment
var folder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
var filePath = Path.Combine(folder, item.Name);
System.IO.File.WriteAllBytes(filePath, item.ContentBytes);
}
}
}
When you get the attachment properties, they will contain information about the attachment.
There are three types of attachments.
First, check the attachment type in the properties' #odata.type and handle them correspondingly.
For fileAttachment types, they contain a contentLocation attribute, which is the URI of the attachment contents.
You can download the attachment from the URI.

Fetching attachment from given .eml file and using that attachment to other mail

I am working on code in C#,but not going through on thing that is I have saved some .eml file on my disk now I am parsing each eml file and creating a new mail adding the eml file data to the new mail but I am unable to attach the attachments present in the .eml file to the new mail , can anybody please help?
I am using the follwing code but it shows the error ex = {"The process cannot access the file because it is being used by another process.\r\n":null}
foreach (CDO.IBodyPart attach in msg.Attachments)
{
i++;
string filenm = "C:\\mail_automation\\attachments\\xyz" + i +".eml";
if (File.Exists(filenm))
{
string fn = attach.FileName;
attach.SaveToFile("C:\\mail_automation\\attachments\\xyz" + i + ".eml");
Attachment data = new Attachment(filenm);
mailMessage.Attachments.Add(data);
}
else
{
File.Create(filenm);
string fn = attach.FileName;
attach.SaveToFile("C:\\mail_automation\\attachments\\xyz" + i + ".eml");
Attachment data = new Attachment(filenm);
mailMessage.Attachments.Add(data);
}
You have to extract the attachments and save them to disk first, then fetch it again into the new mail.
Code example here
MailMessage message = new MailMessage();
MemoryStream ms = new MemoryStream(); //store the mail into this ms 'memory stream'
ms.Position = 0;
message.Attachments.Add(new Attachment(ms, attachmentName));

Post an outlook attachment stream to a rest api

I am developping an outlook add-in, i have to upload mailitem attachment using rest api. First i save the attachment to a temp directory and i create a streamreader to that file, how can i post this stream because if i donĀ“t post the stream it creates me empty files with just the specified name:
for (int i = 1; i <= this.Attachments.Count; i++)
{
var fileName = this.Attachments[i].FileName;
Attachments[i].SaveAsFile(Path.GetTempPath() + fileName);
StreamReader stream = new StreamReader(Path.GetTempPath() + fileName);
}
what i must do to achieve it, i need some help. Cheers

deleting a file in c# after sending email attachment

I have the following code that basically attaches a file to an email message then after all attachments are attached and email is sent, i try to delete all files, however I get a file in use exception. I believe the error comes in this line
Attachment data = new Attachment(file, MediaTypeNames.Application.Octet);
I tried using this code but I get an cannot sent email message
using Attachment data = new Attachment(file, MediaTypeNames.Application.Octet)){
//and the rest of the code in here.
}
foreach (KeyValuePair<string, string> kvp in reports) {
browser.GoTo(kvp.Value);
Thread.Sleep(1000);
System.IO.File.Move(#"C:\Reports\bidata.csv", #"C:\Reports\"+kvp.Key.ToString()+".csv");
string file = #"C:\Reports\" + kvp.Key.ToString() + ".csv";
Attachment data = new Attachment(file, MediaTypeNames.Application.Octet);
// Add time stamp information for the file.
ContentDisposition disposition = data.ContentDisposition;
disposition.CreationDate = System.IO.File.GetCreationTime(file);
disposition.ModificationDate = System.IO.File.GetLastWriteTime(file);
disposition.ReadDate = System.IO.File.GetLastAccessTime(file);
// Add the file attachment to this e-mail message.
mail.Attachments.Add(data);
}
smtpserver.Send(mail);
string[] files = Directory.GetFiles(#"C:\Reports");
foreach (string files1 in files)
{
File.Delete(files1);
}
In order to delete the files first you will have to dispose the attachment and mail objects and then delete the files
Dispose the smtpclient by putting it in a usings or calling dispose directly. That should free the file resource and allow you to nuke it.

Categories

Resources