【问题标题】:Saving attachments using MailKit library ?使用 MailKit 库保存附件?
【发布时间】:2014-08-18 18:45:55
【问题描述】:

我正在尝试学习如何使用 MailKit 库,但我正在努力检索附件。到目前为止,我的代码将打开一个邮箱,浏览每条消息并存储发件人、主题、正文、日期等数据,但我无法处理附件。

我尝试使用在此处、github 和其他网站上找到的其他人的解决方案,但我仍然不明白他们在代码中所做的确切内容,当我接近让解决方案正常工作时,它会导致更多错误,所以我感到压力并删除了所有代码。我并不是要显得懒惰,但如果有人能解释我如何做到这一点,我会很高兴。我基本上是在尝试为 Web 表单应用程序构建邮件客户端。

下面是我的代码,所以你可以看到我相当无能:)

        // 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;

【问题讨论】:

  • 您到底想做什么?您只是想下载附件并将它们保存到磁盘(或某个地方)吗?正文呢?

标签: c# asp.net imap mailkit


【解决方案1】:

我不完全清楚你想要完成什么,但如果你只是想下载邮件附件(而不是下载整个邮件)并将这些附件保存到文件系统,你可以这样做:

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);
    }
}

【讨论】:

  • 嗨,很抱歉延迟回复,我整个周末都不在家。您给出的答案是一个巨大的帮助,我现在可以按我的意愿工作:) 我需要弄清楚如何检查邮件的附件,然后对它们做一些事情,例如写入磁盘。我目前正在尝试构建一个简单的邮件客户端,例如 Gmail、Outlook 等,您可以将其配置到任何邮件服务器,它将检索您的所有邮件并将其本地存储在数据库中,然后将其显示给用户并控制附件文件。抱歉所有问题,但您的图书馆是迄今为止最好的:) 再次感谢!
  • @jstedfast 我在上面尝试了你的代码,我无法获取内联消息,因为它们的 isattachment 属性为 false
  • 不想检查IsAttachment就不需要了
【解决方案2】:

对我有用的另一种选择,但似乎更简单一些:

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);
    }
}

请注意,这是在 Fetch 语句中要求使用 BODYSTRUCTURE 而不是 BODY,这似乎解决了附件未被标记为此类的问题。

【讨论】:

  • 为此欢呼,我已经有一段时间没有看图书馆了,但正在考虑在一个新项目中再次尝试它。自从我上次在这里寻求帮助以来学到了一些东西,但感谢您添加它:)
猜你喜欢
  • 2016-07-13
  • 2015-12-05
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 2021-01-03
  • 2016-05-28
  • 2022-01-17
  • 2014-08-01
相关资源
最近更新 更多