Reputation: 580
I am very curious about this. I am a new hire, and am working on a app that will call the MS 365 api, and crawl the desired mail mailbox. My objective is to filter out any emails with attachments, retrieve the sender name, sender subject, and finally the attachment. This is a console app that will run on a server, so from what i understand, in order to achieve best performance a C# structure is the way to go. This is where I am stuck. I built my structure, with the appropriate properties which I need. Oddly enough I am setting a Byte array property (I never done this). Then in my function I am calling the api, then making a list of my struct in in order to add each email as an object I feel this will improve performance. Now I am able to retrieve the sender of the email, and subject with no issue because they are strings. But now, How can I get the attachment in order to make this a complete email object in memory. This is a snippet of my code.
The Struct:
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;
}
}
}
The email crawler
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);
}
}
}
I now this may seem a bit naive but I been working on this for about 11 hours now, and I have not found any examples on line that can guide me to bring in an attachment to my structure.
Main Objective : I would like to read an email attachment into my structure.
Upvotes: 0
Views: 437
Reputation: 1511
First, there are 2 types of attachments that can be on a Message: ItemAttachments and FileAttachments. ItemAttachments are other Outlook objects (messages, events, etc) that are attached. For these you get an object of the type of attachment, so you won't have the binary data to work with. So I'm assuming you only care about FileAttachments.
As mybirthname said in a comment, you need to loop through each of the attachments. If it's a FileAttachment, then you can use the ContentBytes property to get the byte array of the attachment. Here's what I think it would look like, assuming you change Email_Attachment to a List<>
that can hold all of the attachments:
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);
}
}
This is off the top of my head and untested, so it might have some bugs, but I think it should give you the general idea. Also note that I removed the call to .ToString()
on message.Subject
, since Subject
is already a string. I'm also not sure what calling .ToString()
on the message.Sender
will look like exactly. If you already know that gives you what you want, then great! But you might need to go down to the message.Sender.EmailAddress.Name
or message.Sender.EmailAddress.Address
as appropriate.
As far as whether this would be better as a struct or a class, that really depends on how it's going to be used throughout the rest of the application. This seems like each instance is going to be fairly large, which you usually don't want for structs. However, that's a guideline, not a hard-and-fast rule. How it's used is a much better determinant for whether it should be a class or struct.
Upvotes: 1