使用MailKit / MimeKit从电子邮件中删除附件

时间:2014-06-11 19:15:43

标签: c# email mime mailkit

我正在使用MailKit库处理电子邮件,这些电子邮件一直运行良好。但是,我试图将电子邮件拆分成其组成文件a)主电子邮件(无附件)b)单个附件文件,存储在文件系统上。

我可以单独保存附件,但似乎无法将其从电子邮件正文代码中删除。即它们与主电子邮件一起保存,因此重复数据。 :/

我试过了:

foreach (MimePart part in inMessage.BodyParts)
{ 
    if (part.IsAttachment)
    {
        // Remove MimePart    < This function isn't available on the collection.
    }
}

还尝试过:

var builder = new BodyBuilder();
foreach (MimePart part in inMessage.BodyParts)
{ 
    if (!part.IsAttachment)
    {
        // Add MimeParts to collection    < This function isn't available on the collection.
    }
}
outMessage.Body = builder.ToMessageBody();

如果有人可以帮忙解决这个问题,我会非常感激。

解决方案实施FYI:

private string GetMimeMessageOnly(string outDirPath)
        {
            MimeMessage message = (Master as fsEmail).GetMimeMessage();

            if (message.Attachments.Any())
            {
                var multipart = message.Body as Multipart;
                if (multipart != null)
                {
                    while (message.Attachments.Count() > 0)
                    {
                        multipart.Remove(message.Attachments.ElementAt(0));
                    }
                }
                message.Body = multipart;
            }

            string filePath = outDirPath + Guid.NewGuid().ToString() + ".eml";
            Directory.CreateDirectory(Path.GetDirectoryName(outDirPath));
            using (var cancel = new System.Threading.CancellationTokenSource())
            {    
                using (var stream = File.Create(filePath)) 
                {
                    message.WriteTo(stream, cancel.Token);
                }
            }
            return filePath;
        }

仅获取附件:

private List<string> GetAttachments(string outDirPath)
        {
            MimeMessage message = (Master as fsEmail).GetMimeMessage();

            List<string> list = new List<string>();
            foreach (MimePart attachment in message.Attachments)
            {
                using (var cancel = new System.Threading.CancellationTokenSource())
                {
                    string filePath = outDirPath + Guid.NewGuid().ToString() + Path.GetExtension(attachment.FileName);
                    using (var stream = File.Create(filePath))
                    {
                        attachment.ContentObject.DecodeTo(stream, cancel.Token);
                        list.Add(filePath);
                    }
                }
            }
            return list;
        }

3 个答案:

答案 0 :(得分:5)

您可以检索作为附件的所有MimePart https://github.com/jstedfast/MimeKit/blob/master/MimeKit/MimeMessage.cs#L734,然后对所有Multipart进行迭代,并致电https://github.com/jstedfast/MimeKit/blob/master/MimeKit/Multipart.cs#L468以移除附件。

下面的示例对邮件做了一些假设,例如:只有一个Multipart某些电子邮件客户端(Outlook)非常具有创意,如何制作邮件。

static void Main(string[] args)
{
    var mimeMessage = MimeMessage.Load(@"x:\sample.eml");
    var attachments = mimeMessage.Attachments.ToList();
    if (attachments.Any())
    {
        // Only multipart mails can have attachments
        var multipart = mimeMessage.Body as Multipart;
        if (multipart != null)
        {
            foreach(var attachment in attachments)
            {
                multipart.Remove(attachment);
            }
        }
        mimeMessage.Body = multipart;
    }
    mimeMessage.WriteTo(new FileStream(@"x:\stripped.eml", FileMode.CreateNew));
}

答案 1 :(得分:5)

MimeKit 0.38.0.0开始,您将能够使用MimeIterator遍历MIME树结构,以收集您要删除的附件列表(并删除它们)。为此,您的代码将如下所示:

var attachments = new List<MimePart> ();
var multiparts = new List<Multipart> ();
var iter = new MimeIterator (message);

// collect our list of attachments and their parent multiparts
while (iter.MoveNext ()) {
    var multipart = iter.Parent as Multipart;
    var part = iter.Current as MimePart;

    if (multipart != null && part != null && part.IsAttachment) {
        // keep track of each attachment's parent multipart
        multiparts.Add (multipart);
        attachments.Add (part);
    }
}

// now remove each attachment from its parent multipart...
for (int i = 0; i < attachments.Count; i++)
    multiparts[i].Remove (attachments[i]);

答案 2 :(得分:0)

我创建了一个应用程序,它也可以使用Mailkit下载电子邮件和附件。 我遇到了一个问题:从iOS发送带有附加图片的电子邮件未正确处理。 MailKit没有将图像添加到“附件”列表中。

我使用此方法只获取消息的文本:

private static string GetPlainTextFromMessageBody(MimeMessage message)
    {
        //content type needs to match text/plain otherwise i would store html into DB
        var mimeParts = message.BodyParts.Where(bp => bp.IsAttachment == false && bp.ContentType.Matches("text", "plain"));
        foreach (var mimePart in mimeParts)
        {
            if (mimePart.GetType() == typeof(TextPart))
            {
                var textPart = (TextPart)mimePart;
                return textPart.Text;
            }
        }
        return String.Empty;
    }

这是我用来下载.jpg文件的方法:

foreach (var attachment in message.BodyParts.Where(bp => !string.IsNullOrEmpty(bp.FileName)))
{
    if (attachment.FileName.ToLowerInvariant().EndsWith(".jpg"))
    {
        //do something with the image here
    }
}