Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用Mailkit下载电子邮件附件_C#_Asp.net_Imap_Mime_Mailkit - Fatal编程技术网

C# 如何使用Mailkit下载电子邮件附件

C# 如何使用Mailkit下载电子邮件附件,c#,asp.net,imap,mime,mailkit,C#,Asp.net,Imap,Mime,Mailkit,我正在使用中的代码使用MailKit从邮件下载附件。在检索附件的foreach循环中,它总是返回空。因为它是空的,所以不进入foreach循环。如果我做错了什么,请纠正我 var messages = client.Inbox.Fetch(0, -1, MessageSummaryItems.Full | MessageSummaryItems.UniqueId); int unnamed = 0; foreach (var message in

我正在使用中的代码使用MailKit从邮件下载附件。在检索附件的foreach循环中,它总是返回空。因为它是空的,所以不进入foreach循环。如果我做错了什么,请纠正我

        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)
            {

                //Here the attachments is always empty even though my mail has email with attachements
                var attachments = multipart.BodyParts.OfType<BodyPartBasic>().Where(x => x.IsAttachment);
                foreach (var attachment in 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);
                }
            }
            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.UniqueId);
int unnamed=0;
foreach(消息中的var消息)
{
var multipart=message.Body作为BodyPartMultipart;
var basic=消息体作为BodyPartBasic;
如果(多部分!=null)
{
//这里的附件总是空的,即使我的邮件中有带有附件的电子邮件
var attachments=multipart.BodyParts.OfType(),其中(x=>x.IsAttachment);
foreach(附件中的var附件)
{
var mime=(MimePart)client.Inbox.GetBodyPart(message.UniqueId.Value,附件);
var fileName=mime.fileName;
if(string.IsNullOrEmpty(文件名))
fileName=string.Format(“未命名-{0}”,++未命名);
使用(var stream=File.Create(文件名))
mime.ContentObject.DecodeTo(流);
}
}
else if(basic!=null&&basic.IsAttachment)
{
var mime=(MimePart)client.Inbox.GetBodyPart(message.UniqueId.Value,basic);
var fileName=mime.fileName;
if(string.IsNullOrEmpty(文件名))
fileName=string.Format(“未命名-{0}”,++未命名);
使用(var stream=File.Create(文件名))
mime.ContentObject.DecodeTo(流);
}
}

首先要注意的是MIME是一个树结构,而不是一个平面列表。BodyPartMultipart可以包含其他BodyPartMultipart子项以及BodyPartBasic子项,因此当您遇到另一个BodyPartMultipart时,您也需要深入到该子项中

我的猜测是,您正在检查的消息具有嵌套的多部分,这就是您遇到问题的原因


或者“附件”没有一个值为“附件”的内容处理头。

下面是我用来遍历MIME树结构以获取所有可能的附件的方法。请注意,至少在我测试的电子邮件中,
IsAttachment
标志从未设置为
true

首先,创建一个递归函数,以
IEnumerable
的形式检索所有基本正文部分(包含消息实际内容的MIME消息部分):

私有静态IEnumerable GetBasicBodyParts(此BodyPart)
{
var multipart=零件作为BodyPartMultipart;
var basic=零件作为BodyPartBasic;
如果(多部分!=null)
{
foreach(多部分车身部件中的var子部分)
{
如果(子部分为BodyPartBasic)
{
将返回子部分作为BodyPartBasic;
}
其他的
{
foreach(子部分GetBasicBodyParts()中的var子部分)
{
收益子部分;
}
}
}
}else if(基本!=null)
{
基本收益率;
}
其他的
{
屈服断裂;
}
}
然后将该函数放在“下载”函数中使用,该函数与@jstedfast在其他帖子中提供的非常类似:

public static IEnumerable<FileInfo> DownloadAttachments(this EmailClient client, IMessageSummary message,
    string destination)
{
    fileNameFilter = fileNameFilter ?? AlwaysTrue;
    if (!Directory.Exists(destination))
        Directory.CreateDirectory(destination);

    var folder = client.Inbox;
    folder.Open(FolderAccess.ReadOnly);
    foreach (var part in message.Body.GetBasicBodyParts())
    {

        var mimeHeader = (MimePart) folder.GetBodyPart(message.UniqueId.Value, part, headersOnly: true);
        var headerFileName = mimeHeader.FileName;
        if (string.IsNullOrWhiteSpace(headerFileName))
            continue;


        var mime = (MimePart) folder.GetBodyPart(message.UniqueId.Value, part);
        var fileName = mime.FileName;

        var filePath = Path.Combine(destination, fileName);
        using (var stream = File.Create(filePath))
            mime.ContentObject.DecodeTo(stream);

        yield return new FileInfo(filePath);
    }
}
公共静态IEnumerable DownloadAttachments(此EmailClient客户端、IMessageSummary邮件、,
字符串目的地)
{
fileNameFilter=fileNameFilter±AlwaysTrue;
如果(!Directory.Exists(destination))
CreateDirectory(目的地);
var folder=client.Inbox;
folder.Open(FolderAccess.ReadOnly);
foreach(message.Body.GetBasicBodyParts()中的var部分)
{
var mimeHeader=(MimePart)folder.GetBodyPart(message.UniqueId.Value,part,headersOnly:true);
var headerFileName=mimeHeader.FileName;
if(string.IsNullOrWhiteSpace(headerFileName))
继续;
var mime=(MimePart)folder.GetBodyPart(message.UniqueId.Value,part);
var fileName=mime.fileName;
var filePath=Path.Combine(目标,文件名);
使用(var stream=File.Create(filePath))
mime.ContentObject.DecodeTo(流);
返回新的FileInfo(filePath);
}
}
请注意,此功能:

  • 跳过没有文件名的文件。如果要保留这些文件,可以从@jstedfast的其他示例中添加
    unnamed
    计数器。您还可以添加其他逻辑,根据文件名或MIME头中的其他信息筛选出文件
  • 首先只下载附件的标题。这允许文件名过滤,而无需先下载内容
  • 是一种扩展方法,因此可以像这样使用:
    client.DownloadAttachments(someMessage,@“C:\tmp\attachments”)
  • 为保存的每个附件返回
    System.IO.FileInfo
    对象。这对我很有用,但可能与其他人无关。这不是绝对必要的

我希望这对其他人有所帮助。

您能提供任何示例或解决方法,以便通过上述过程下载附件。我对MIME树结构不熟悉,我将尝试浏览您的文档。
public static IEnumerable<FileInfo> DownloadAttachments(this EmailClient client, IMessageSummary message,
    string destination)
{
    fileNameFilter = fileNameFilter ?? AlwaysTrue;
    if (!Directory.Exists(destination))
        Directory.CreateDirectory(destination);

    var folder = client.Inbox;
    folder.Open(FolderAccess.ReadOnly);
    foreach (var part in message.Body.GetBasicBodyParts())
    {

        var mimeHeader = (MimePart) folder.GetBodyPart(message.UniqueId.Value, part, headersOnly: true);
        var headerFileName = mimeHeader.FileName;
        if (string.IsNullOrWhiteSpace(headerFileName))
            continue;


        var mime = (MimePart) folder.GetBodyPart(message.UniqueId.Value, part);
        var fileName = mime.FileName;

        var filePath = Path.Combine(destination, fileName);
        using (var stream = File.Create(filePath))
            mime.ContentObject.DecodeTo(stream);

        yield return new FileInfo(filePath);
    }
}