I actually had this working for .pdf
files and could not get it to work for .xls
.
Now I cannot seem to get ether to work. Note I have looked at all other post from jsteadfast and this is the code I came up with.
When I read the Message I have nothing in Attachments there are 2 files the body of the text in a .txt
file and the attachment which is in the .pdf
or .xls
file both are in message.BodyParts
.
I just want to save the attachments to a file share. This is a .NET worker service. Azure Active Directory. Mailbox is outlook.office365.com.
In my stream I get
"WriteTimeout = {stream.WriteTimeout' threw an exception of type 'System.InvalidOperationException}"
using (var imapclient = new ImapClient())
{
imapclient.Connect(mailbox, port, SecureSocketOptions.SslOnConnect, stoppingToken);
imapclient.AuthenticationMechanisms.Remove(authenticationResult.AccessToken);
imapclient.Authenticate(new SaslMechanismOAuth2(userName, authenticationResult.AccessToken), stoppingToken);
imapclient.Inbox.Open(FolderAccess.ReadWrite);
var messages = imapclient.Inbox.Fetch(0, -1, MessageSummaryItems.Full | MessageSummaryItems.UniqueId);
int unnamed = 0;
foreach (var message in messages)
{
var multipart = message.Body as BodyPartMultipart;
var basic = message.Body as BodyPartBasic;
var bodyParts = message.BodyParts.ToList(); //Foreach message.BodyParts bodyParts[0] contains .txt, bodyParts[1] contains .pdf
var archive = imapclient.GetFolder(_archive);
if (multipart != null)
{
foreach (var attachment in bodyParts)
{
if (!string.IsNullOrEmpty(attachment.FileName)) //when it's .pdf it has a FileName
{
var mime = (MimePart)imapclient.Inbox.GetBodyPart(message.UniqueId, attachment);
var fileName = mime.FileName;
if (string.IsNullOrEmpty(fileName))
fileName = string.Format("unnamed-{0}", ++unnamed);
using (var stream = File.Create(fileName))
{
string[] splitFileName = fileName.Split(".");
fileName = splitFileName[0] + string.Format("_{0:MM-dd-yyyy_HH-mm-ss-fff}", DateTime.Now) + "." + splitFileName[1];
//SaveStreamToDirectory(stream, fileName, armadaTargetDir);
using (var fileStream = new FileStream(Path.Combine(armadaTargetDir, fileName), FileMode.Create, FileAccess.Write))
{
stream.CopyTo(fileStream);
}
}
//imapclient.Inbox.MoveTo(message.UniqueId, archive);
}
}
}
else if (basic != null && basic.IsAttachment)
{
var mime = (MimePart)imapclient.Inbox.GetBodyPart(message.UniqueId, basic);
var fileName = mime.FileName;
if (string.IsNullOrEmpty(fileName))
fileName = string.Format("unnamed-{0}", ++unnamed);
using (var stream = File.Create(fileName))
mime.ContentObject.DecodeTo(stream);
}
}
}
I have also tried the following code example that should work as well according to jsteadfast. As you can see here I am trying to set the stream.Position. Just to be clear the file is being saved to the file share. but with no data. Any help would be greatly appreciated.
using (var imapclient = new ImapClient())
{
imapclient.Connect(mailbox, port, SecureSocketOptions.SslOnConnect, stoppingToken);
imapclient.AuthenticationMechanisms.Remove(authenticationResult.AccessToken);
imapclient.Authenticate(new SaslMechanismOAuth2(userName, authenticationResult.AccessToken), stoppingToken);
imapclient.Inbox.Open(FolderAccess.ReadWrite);
var messages = imapclient.Inbox.Fetch(0, -1, MessageSummaryItems.Full | MessageSummaryItems.UniqueId);
int unnamed = 0;
IList<UniqueId> uids = imapclient.Inbox.Search(SearchQuery.All);
foreach (UniqueId uid in uids)
{
MimeMessage message = imapclient.Inbox.GetMessage(uid);
foreach (MimeEntity attachment in message.Attachments)
{
var fileName = attachment.ContentDisposition?.FileName ?? attachment.ContentType.Name;
using (var stream = File.Create(fileName))
{
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
if (attachment is MessagePart)
{
var rfc822 = (MessagePart)attachment;
rfc822.Message.WriteTo(stream);
}
else
{
var part = (MimePart)attachment;
part.Content.DecodeTo(stream);
}
SaveStreamToDirectory(stream, fileName, armadaTargetDir);
}
}
}