将电子邮件附件获取到 C# 结构中

Getting an email attachment into a C# structure

我对此很好奇。我是一名新员工,正在开发一个将调用 MS 365 api 并抓取所需邮箱的应用程序。我的 objective 是过滤掉所有带附件的电子邮件,检索发件人姓名、发件人主题,最后是附件。这是一个将在服务器上 运行 的控制台应用程序,因此据我了解,为了获得最佳性能,C# 结构是可行的方法。这就是我被困的地方。我用我需要的适当属性构建了我的结构。奇怪的是我正在设置一个字节数组 属性 (我从来没有这样做过)。然后在我的函数中,我调用 api,然后列出我的结构,以便将每封电子邮件添加为一个对象,我认为这会提高性能。现在我可以毫无问题地检索电子邮件的发件人和主题,因为它们是字符串。但是现在,我怎样才能得到附件才能使它成为内存中的完整电子邮件对象。这是我的代码片段。

结构:

struct Emailed_Expenses
{
    private string sender;
    private string subject;
    private byte [] attachment;        

    public string Email_Sender
    {
        get
        {
            return sender;
        }
        set
        {
            sender = value;
        }
    }
    public string Email_Subject
    {
        get
        {
            return subject;
        }
        set
        {
            subject = value;
        }
    } 
    public byte[] Email_Attachment
    {
        get
        {
            return attachment;
        }
        set
        {
            attachment = value;
        }
    }
}

电子邮件爬虫

        public static List<Emailed_Expenses> Get_Star_Mailbox()
    {
        //var star_user = "*******@dell.com";
        OutlookServicesClient star_Mail_Box = Start_OutLook_Services();
        List<Emailed_Expenses> star_Inbox = new List<Emailed_Expenses>();

        try
        {

            var Email_Box = star_Mail_Box.Users["******@dell.com"].Messages.ExecuteAsync().Result;

            var messages = Email_Box.CurrentPage;
            //var messages = star_Mail_Box.Me.Folders["Inbox"].Messages.OrderByDescending(m => m.DateTimeReceived).Take(10).ExecuteAsync();

            foreach (var message in messages)
            {
                if (message.Attachments.CurrentPage.Count > 0)
                {
                    Emailed_Expenses email = new Emailed_Expenses
                    {
                        Email_Sender = message.Sender.ToString(),
                        Email_Subject = message.Subject.ToString(),
                        >>>>>>>>Email_Attachment = byte [message.Attachments],<<<<< this is what I am talking about !!!!*****
                    };

                    star_Inbox.Add(email);
                }

            }
        }

我现在这看起来有点天真,但我已经为此工作了大约 11 个小时,而且我还没有在网上找到任何可以指导我将附件添加到我的结构中的示例。

Main Objective : 我想将电子邮件附件读入我的结构。

首先,邮件中可以包含两种类型的附件:ItemAttachments 和 FileAttachments。 ItemAttachments 是附加的其他 Outlook 对象(邮件、事件等)。对于这些,您将获得一个附件类型的对象,因此您将无法使用二进制数据。所以我假设您只关心 FileAttachments。

正如 mybirthname 在评论中所说,您需要遍历每个附件。如果它是一个 FileAttachment,那么您可以使用 ContentBytes 属性 来获取附件的字节数组。这是我认为的样子,假设您将 Email_Attachment 更改为可以容纳所有附件的 List<>

foreach (var message in messages)
{
    Emailed_Expenses email = null;

    foreach (var attachment in message.Attachments.CurrentPage)
    {
        FileAttachment file = attachment as FileAttachment;
        if (file != null)
        {
            if (email == null)
            {
                email = new Emailed_Expenses
                {
                    Email_Sender = message.Sender.ToString(),
                    Email_Subject = message.Subject,
                    Email_Attachment = new List<byte[]>
                };
            }

            email.Email_Attachment.Add(file.ContentBytes);
        }
    }

    if (file != null)
    {
        star_Inbox.Add(email);
    }
}

这是我的想法,未经测试,所以它可能有一些错误,但我认为它应该给你一个大概的想法。另请注意,我在 message.Subject 上删除了对 .ToString() 的调用,因为 Subject 已经是一个字符串。我也不确定在 message.Sender 上调用 .ToString() 会是什么样子。如果您已经知道这会给您想要的东西,那就太好了!但是您可能需要根据需要转到 message.Sender.EmailAddress.Namemessage.Sender.EmailAddress.Address

至于这是结构更好还是 class,这实际上取决于它在整个应用程序的其余部分中的使用方式。这似乎每个实例都将相当大,您通常不需要结构。但是,这是一个准则,而不是 hard-and-fast 规则。它的使用方式更好地决定了它应该是 class 还是结构。