Сохранение вложений с помощью библиотеки MailKit?

Я пытаюсь узнать, как использовать библиотеку MailKit, но я изо всех сил пытаюсь получить вложения. Пока мой код будет открывать почтовый ящик, просматривать каждое сообщение и хранить данные, такие как отправитель, тема, тело, дата и т. д. но я не могу иметь дело с привязанностями.

Я пытался использовать решения других людей, найденные здесь, на github и других сайтах, но я все еще не понимаю, что они делают в своем коде, и когда я приближаюсь к решению, которое работает, это вызывает больше ошибок, поэтому я получаю стресс и удаляю весь код. Я не хочу показаться ленивым, но я бы хотел, чтобы кто-нибудь объяснил, как я могу этого достичь. Я в основном пытаюсь создать почтовый клиент для приложения веб-форм.

ниже мой код, так как вы можете видеть, я довольно невежественный :)

        // Open the Inbox folder
        client.Inbox.Open(FolderAccess.ReadOnly, cancel.Token);

        //get the full summary information to retrieve all details
        var summary = client.Inbox.Fetch(0, -1, MessageSummaryItems.Full, cancel.Token);
        foreach (var msg in summary)
        {
            //this code originally downloaded just the text from the body
            var text = msg.Body as BodyPartText;
            //but I tried altering it so that it will get attachments here also
            var attachments = msg.Body as BodyPartBasic;

            if (text == null)
            {
                var multipart = msg.Body as BodyPartMultipart;

                if (multipart != null)
                {
                    text = multipart.BodyParts.OfType<BodyPartText>().FirstOrDefault();
                }
            }

            if (text == null)
                continue;

            //I hoped this would get the messages where the content dispositon was not null
            //and let me do something like save the attachments somewhere but instead it throws exceptions
            //about the object reference not set to an instance of the object so it's very wrong
            if (attachments.ContentDisposition != null && attachments.ContentDisposition.IsAttachment)
            {
                //I tried to do the same as I did with the text here and grab the body part....... but no 
                var attachedpart = client.Inbox.GetBodyPart(msg.Index, attachments, cancel.Token);
            }

            else 
            {
                //there is no plan b :(
            }

            // this will download *just* the text 
            var part = client.Inbox.GetBodyPart(msg.Index, text, cancel.Token);
            //cast main body text to Text Part
            TextPart _body = (TextPart)part;

2 ответов


Я не совсем понимаю, что вы хотите сделать, но если вы просто хотите загрузить вложения сообщений (без загрузки всего сообщения) и сохранить эти вложения в файловой системе, вот как вы можете это сделать:

var messages = client.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;

    if (multipart != null) {
        foreach (var attachment in multipart.BodyParts.OfType<BodyPartBasic> ().Where (x => x.IsAttachment)) {
            var mime = (MimePart) client.Inbox.GetBodyPart (message.UniqueId.Value, attachment);
            var fileName = mime.FileName;

            if (string.IsNullOrEmpty (fileName))
                fileName = string.Format ("unnamed-{0}", ++unnamed);

            using (var stream = File.Create (fileName))
                mime.ContentObject.DecodeTo (stream);
        }
    } else if (basic != null && basic.IsAttachment) {
        var mime = (MimePart) client.Inbox.GetBodyPart (message.UniqueId.Value, 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);
    }
}

еще одна альтернатива, которая работает для меня, но кажется немного проще:

var messages = client.Inbox.Fetch (0, -1, MessageSummaryItems.Full | MessageSummaryItems.BodyStructure | MessageSummaryItems.UniqueId);
int unnamed = 0;

foreach (var message in messages) {
    foreach (var attachment in message.Attachments) {
        var mime = (MimePart) client.Inbox.GetBodyPart (message.UniqueId.Value, attachment);
        var fileName = mime.FileName;

        if (string.IsNullOrEmpty (fileName))
            fileName = string.Format ("unnamed-{0}", ++unnamed);

        using (var stream = File.Create (fileName))
            mime.ContentObject.DecodeTo (stream);
    }
}

обратите внимание, что это запрашивает BODYSTRUCTURE вместо тела в операторе Fetch, который, похоже, устраняет проблему вложений, не помеченных как таковые.