Search code examples
c#.netimapmailkitmimekit

c# - MailKit imap download attachments in memory/byte[] (No access to the file system)


I need to download attachments from an email, i'm using imap (using MailKit) I don't have access to the file system, I have to convert it to byte[], since I have to store it in an azure storage.

I have tried this example: http://www.mimekit.net/docs/html/M_MailKit_Net_Imap_ImapFolder_GetBodyPartAsync.htm

But again I don't have access to the file system, I have to convert it to byte[], since I have to store it in an azure storage.

I've also tried this one: MailKit: How to download all attachments locally from a MimeMessage

But again it is stored locally in the file system.

Here is the code, but as currently writes it to the local file system: `

await client.Inbox.OpenAsync(FolderAccess.ReadOnly);
var items = await client.Inbox.FetchAsync(new List<UniqueId>() { new UniqueId(uid) }, MessageSummaryItems.UniqueId | MessageSummaryItems.BodyStructure);

foreach (var item in items)
{
    var bodyPart = item.TextBody;

    foreach (var attachment in item.Attachments)
    {
        var entity = await client.Inbox.GetBodyPartAsync(item.UniqueId, attachment);
        var fileName = attachment.ContentDisposition?.FileName ?? attachment.ContentType.Name;
        var directory = @"C:\temp\mails";
        
        if (entity is MessagePart)
        {
            var rfc822 = (MessagePart)entity;
            var path = Path.Combine(directory, fileName);
            await rfc822.Message.WriteToAsync(path);
        }
        else
        {
            var part = (MimePart)entity;                                
            var path = Path.Combine(directory, fileName);
            using (var stream = File.Create(path))
                await part.Content.DecodeToAsync(stream);
        }
    }
}

`

I've tried this, but the file that comes out of this doesn't work `

var directory = @"C:\temp\mails";
using (var stream = new MemoryStream())
{
    if (entity is MessagePart)
    {
        var rfc822 = (MessagePart)entity;
        await rfc822.Message.WriteToAsync(stream);
    }
    else
    {
        var part = (MimePart)entity;
        await part.Content.DecodeToAsync(stream);
    }

    //To test if the file is converted, and readable
    var byteArr = stream.ToByteArray();
    File.WriteAllBytes(Path.Combine(directory, fileName), byteArr);
}

`


Solution

  • Thanks @ckuri, the solution is:

    var byteArr = stream.ToArray();