3
votes

I have written a program that successfully uses the Graph API to check a mailbox and retrieve messages. If a message contains a standard attachment (e.g., PDF, Word document) then the code works. I can see in debug that these are considered a "FileAttachment" type. However, if the message contains an attachment that is another email, or a .wav file that is a voicemail message (which seems odd to me) then the program chokes because these attachments are of type ItemAttachment and the cast fails. The relevant code is this:

var msgTask = GraphClient.Me.MailFolders.Inbox.Messages.Request().Filter(filter).Expand("attachments").GetAsync();
IMailFolderMessagesCollectionPage messages = msgTask.Result;
foreach (Message msg in messages)
{
    // ...  
    foreach (Attachment att in msg.Attachments)
    {
        FileAttachment attachment = (FileAttachment)att;
        MsgFile.Attachments.Add(new System.IO.MemoryStream(attachment.ContentBytes), attachment.Name);
    }
}

I've done a bit of searching and I'm finding documentation using REST to get at the data associated with an ItemAttachment, but I'm not using REST, at least not directly. This is a Windows command line application, and using NuGet I have downloaded the Microsoft.Graph and Microsoft.Graph.Core packages. These are the libraries that I'm using everywhere else in my code to authenticate and access Office 365 data.

So, I'm wondering if anyone has any insight about how to use these libraries to access and download ItemAttachment objects. Googling for info about the Graph API is almost always about REST. I have found some sample code using these libraries, but none of it deals with ItemAttachments.

1
In my experience you should not expect those Wrapper-Nuget-Libs to be feature-complete. The products (in your case Graph API) are evolving too fast and the maintainers of the packages are often not picking up the pace. My suggestion would be to switch to REST and build your own "lib" as a wrapper.Alexander Schmidt

1 Answers

1
votes

Item that is attached to the message could be requested like this (documentation):

var attachmentRequest = graphClient.Me.MailFolders.Inbox.Messages[message.Id]
                                .Attachments[attachment.Id].Request().Expand("microsoft.graph.itemattachment/item").GetAsync();
var itemAttachment = (ItemAttachment)attachmentRequest.Result;
var itemMessage = (Message) itemAttachment.Item;  //get attached message
Console.WriteLine(itemMessage.Body);  //print message body

Example

Demonstrates how to get attachments and save it into file if attachment is a file and read the attached message if attachment is an item:

var request = graphClient.Me.MailFolders.Inbox.Messages.Request().Expand("attachments").GetAsync();
var messages = request.Result;
foreach (var message in messages)
{
     foreach(var attachment in message.Attachments)
     {
          if (attachment.ODataType == "#microsoft.graph.itemAttachment")
          {

              var attachmentRequest = graphClient.Me.MailFolders.Inbox.Messages[message.Id]
                            .Attachments[attachment.Id].Request().Expand("microsoft.graph.itemattachment/item").GetAsync();
              var itemAttachment = (ItemAttachment)attachmentRequest.Result;
              var itemMessage = (Message) itemAttachment.Item;  //get attached message
              //...
          }
          else
          {
               var fileAttachment = (FileAttachment)attachment;
               System.IO.File.WriteAllBytes(System.IO.Path.Combine(downloadPath,fileAttachment.Name), fileAttachment.ContentBytes);
         }
     }
}