none
Outlook Add-in Feature that uploads to sharepoint library has issue "only" with .msg attachments. RRS feed

  • Question

  • Hi,

    I have an application where you right click an email with an attachment, it will take that email's attachment's and upload them to sharepoint libraries.  Sharepoint sites are persisted and updated from an admin screen into hidden storageitems.  I basically have a form which lets you select the sharepoint site to upload to after you right click.. and then it calls this to pop it up into sharepoint.   Everything works swimmingly for every attachment type, multiple attachments, etc.. except for attachments of other emails.  I'm using the following schemas:

            // below is populated when ATTACH_BY_VALUE for PR_ATTACH_METHOD
            const string PR_ATTACH_DATA_BIN = "http://schemas.microsoft.com/mapi/proptag/0x37010102";
    
            // P_LONG..  
            const string PR_ATTACH_METHOD = "http://schemas.microsoft.com/mapi/proptag/0x37050003";
    
            // below is populated when ATTACH_EMBEDDED_MSG is for PR_Attach_method
            const string PR_ATTACH_DATA_OBJ = "http://schemas.microsoft.com/mapi/proptag/0x3701000D";

    So here is the actual code.   I ran the code to see that a normal attachment returns a 1, and an email attachment returns a 5.  If I try to run an email attachment with the GetProperty(PR_ATTACH_DATA_BIN) it returns error that the schema is not found/valid or something to that effect.   Problem being, it would seem based on what I've read that this should actually work if I use ATTACH_EMBEDDED_MSG, but it doesn't.   So this code functions perfectly unless one of the attachments on the email is another email.  

            public void AttachmentSharepoint(Outlook.MailItem mailItem, string clientContextURL, string sitelibfolder)
            {
                if (mailItem != null)
                {
                    var attachments = mailItem.Attachments;
                    foreach (Outlook.Attachment attachment in attachments)
                    {             
                        // first look at PR_ATTACH_METHOD then determine which property to use.
                        var attachtypevar = attachment.PropertyAccessor.GetProperty(PR_ATTACH_METHOD);
                        int attachtype = Convert.ToInt32(attachtypevar);
                        byte[] attachmentData = null;
    
                        if (attachtype == 1)
                        {
                            // this is a standard attached object
                           attachmentData = attachment.PropertyAccessor.GetProperty(PR_ATTACH_DATA_BIN) as byte[];
                        }
                        else if (attachtype == 5)
                        {   
                            // this is email, so we can't use BIN, must use OBJ instead
                            attachmentData = attachment.PropertyAccessor.GetProperty(PR_ATTACH_DATA_OBJ) as byte[]; 
                        }
                        MemoryStream theMemStream = new MemoryStream();
                        theMemStream.Write(attachmentData, 0, attachmentData.Length);
                        theMemStream.Position = 0;
                        try
                        {
                            bool overwrite = checkOverwrite.Checked;
                            ClientContext clientContext = new ClientContext(clientContextURL);
                            using (theMemStream)
                                ClientOM.File.SaveBinaryDirect(clientContext, sitelibfolder + attachment.FileName, theMemStream, overwrite);
                            // save configuration
                            checkurllist(clientContextURL + sitelibfolder);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message);
                        }
    
                    }
                }
            }

    Any help would be appreciated.        


    • Edited by Scott-ATX Wednesday, February 29, 2012 1:36 AM wording
    Wednesday, February 29, 2012 1:34 AM

Answers

  • PR_ATTACH_DATA_BIN isn't a PT_OBJECT, it's a PT_BINARY property (just look at the tag name). That's binary array of data and is supported for use with PropertyAccessor.
     
    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     
    "Scott-ATX" <=?utf-8?B?U2NvdHQtQVRY?=> wrote in message news:513f4022-8f09-4d80-8e65-25e835d41939...

    Thanks for you response.   On this:  "PR_ATTACH_DATA_OBJ is a PT_OBJECT, that type of property isn't supported for use with PropertyAccessor."

    PR_ATTACH_DATA_BIN is also a PT_OBJECT, and I can get that with PropertyAccessor just fine (if the attachment is not a .MSG)


    Ken Slovak MVP - Outlook
    Wednesday, February 29, 2012 7:22 PM
    Moderator
  • I don't know if Redemption is an option for you, but it does let you directly get an RDOMail object from the embedded item attachment.
     
    That can be cast to whatever actual type (RDOContact, RDOAppointment, etc.) or left as RDOMail (more or less an IMessage), and Redemption can be used from C#.

    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     
    "Scott-ATX" <=?utf-8?B?U2NvdHQtQVRY?=> wrote in message news:69917ced-ee34-4222-8873-cf91cf06a770...

    Oops, you're right.  My bad.

    Thanks again for your feedback.

    I've found some more info on this particular issue and it looks like there are some C++ solutions but no other workaround in C# (except for saving to disk option as mentioned).  Also, Was researching if perhaps I could get entryID and pull it that way, but apparently embedded attachments have their entry ID stripped.

    For anyone else researching this, here is a related writeup:  http://msdn.microsoft.com/en-us/library/cc842411.aspx 

    And for folks that want to use my example above, here is some additional info:

    using Microsoft.SharePoint.Client;
    using ClientOM = Microsoft.SharePoint.Client;
    using System.IO;
    using System.Net;

    And, a working input format for clientcontentURL and sitelibfolder is specifically:

    http://moss.blah.com     and       /sites/SITENAME/Shared Documents/subfoldername/


    Ken Slovak MVP - Outlook
    Thursday, March 1, 2012 7:03 PM
    Moderator

All replies

  • Maybe change the code to save attachments to temporary files in disk which you read later to upload to sharepoint. This way it will work always - this is how i do this.
    Wednesday, February 29, 2012 8:25 AM
  • Specifically, here is the error I receive:

    {"Object does not support property \"http://schemas.microsoft.com/mapi/proptag/0x3701000D\"."}

    From this line: attachmentData = attachment.PropertyAccessor.GetProperty(PR_ATTACH_DATA_OBJ) as byte[];

    Alternatively (where I first encountered issue) If I try to get the .msg attachment via:    attachmentData = attachment.PropertyAccessor.GetProperty(PR_ATTACH_DATA_BIN) as byte[];   That fails with similar message for the PR_ATTACH_DATA_BIN schema saying it's property is not supported.   Calling the same exact line with PR_ATTACH_DATA_BIN with a normal attachment (pdf, docx, txt, bin, etc) works without issue.  

    The documentation below is what I was going off of, thinking PR_ATTACH_DATA_OBJ should contain the attachment data if PR_ATTACH_METHOD was set as ATTACH_EMBEDDED_MSG.. for Emails:

    //PR_ATTACH_DATA_BIN            0x37010102 The PR_ATTACH_DATA_BIN property holds the attachment when the value of the PR_ATTACH_METHOD property is ATTACH_BY_VALUE (aka 1), which is the usual attachment method and the only one required to be supported.
    //PR_ATTACH_DATA_OBJ            0x3701000D The PR_ATTACH_DATA_OBJ property holds the attachment when the value of the PR_ATTACH_METHOD property is ATTACH_EMBEDDED_MSG (aka 5) 

    I have considered saving to disk, but really want to keep it all in-memory if possible.   Wondering if this is a bug, not supported, info I have is wrong, or my implementation is bad.

    Thanks!


    • Edited by Scott-ATX Wednesday, February 29, 2012 3:33 PM wording
    Wednesday, February 29, 2012 3:29 PM
  • PR_ATTACH_DATA_OBJ is a PT_OBJECT, that type of property isn't supported for use with PropertyAccessor.
     
    http://msdn.microsoft.com/en-us/library/cc842329.aspx has information on that property.
     
    I'd save it out to the file system if you can't use Extended MAPI (C++ or Delphi/Pascal only) or Redemption (www.dimastr.com/redemption). Redemption has an EmbeddedMsg object property on RDOAttachment objects that represents an RDOMail object, so when using Redemption all the messy work is already done for you.
     
    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     
    "Scott-ATX" <=?utf-8?B?U2NvdHQtQVRY?=> wrote in message news:24ee2866-b188-4ed7-9eb8-a6a8fe6f424c...

    Specifically, here is the error I receive:

    {"Object does not support property \"http://schemas.microsoft.com/mapi/proptag/0x3701000D\"."}

    From this line: attachmentData = attachment.PropertyAccessor.GetProperty(PR_ATTACH_DATA_OBJ) as byte[];

    Alternatively (where I first encountered issue) If I try to get the ..msg attachment via:    attachmentData = attachment.PropertyAccessor.GetProperty(PR_ATTACH_DATA_BIN) as byte[];   That fails with similar message for the PR_ATTACH_DATA_BIN schema saying it's property is not supported.   Calling the same exact line with PR_ATTACH_DATA_BIN with a normal attachment (pdf, docx, txt, bin, etc) works without issue.  

    The documentation below is what I was going off of, thinking PR_ATTACH_DATA_OBJ should contain the attachment data if PR_ATTACH_METHOD was set as ATTACH_EMBEDDED_MSG.. for Emails:

    //PR_ATTACH_DATA_BIN            0x37010102 The PR_ATTACH_DATA_BIN property holds the attachment when the value of the PR_ATTACH_METHOD property is ATTACH_BY_VALUE (aka 1), which is the usual attachment method and the only one required to be supported.
    //PR_ATTACH_DATA_OBJ            0x3701000D The PR_ATTACH_DATA_OBJ property holds the attachment when the value of the PR_ATTACH_METHOD property is ATTACH_EMBEDDED_MSG (aka 5) 

    I have considered saving to disk, but really want to keep it all in-memory if possible.   Wondering if this is a bug, not supported, info I have is wrong, or my implementation is bad.

    Thanks!



    Ken Slovak MVP - Outlook
    Wednesday, February 29, 2012 4:57 PM
    Moderator
  • Thanks for you response.   On this:  "PR_ATTACH_DATA_OBJ is a PT_OBJECT, that type of property isn't supported for use with PropertyAccessor."

    PR_ATTACH_DATA_BIN is also a PT_OBJECT, and I can get that with PropertyAccessor just fine (if the attachment is not a .MSG)

    Wednesday, February 29, 2012 6:56 PM
  • PR_ATTACH_DATA_BIN isn't a PT_OBJECT, it's a PT_BINARY property (just look at the tag name). That's binary array of data and is supported for use with PropertyAccessor.
     
    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     
    "Scott-ATX" <=?utf-8?B?U2NvdHQtQVRY?=> wrote in message news:513f4022-8f09-4d80-8e65-25e835d41939...

    Thanks for you response.   On this:  "PR_ATTACH_DATA_OBJ is a PT_OBJECT, that type of property isn't supported for use with PropertyAccessor."

    PR_ATTACH_DATA_BIN is also a PT_OBJECT, and I can get that with PropertyAccessor just fine (if the attachment is not a .MSG)


    Ken Slovak MVP - Outlook
    Wednesday, February 29, 2012 7:22 PM
    Moderator
  • Oops, you're right.  My bad.

    Thanks again for your feedback.

    I've found some more info on this particular issue and it looks like there are some C++ solutions but no other workaround in C# (except for saving to disk option as mentioned).  Also, Was researching if perhaps I could get entryID and pull it that way, but apparently embedded attachments have their entry ID stripped.

    For anyone else researching this, here is a related writeup:  http://msdn.microsoft.com/en-us/library/cc842411.aspx 

    And for folks that want to use my example above, here is some additional info:

    using Microsoft.SharePoint.Client;
    using ClientOM = Microsoft.SharePoint.Client;
    using System.IO;
    using System.Net;

    And, a working input format for clientcontentURL and sitelibfolder is specifically:

    http://moss.blah.com     and       /sites/SITENAME/Shared Documents/subfoldername/

    Thursday, March 1, 2012 6:53 PM
  • I don't know if Redemption is an option for you, but it does let you directly get an RDOMail object from the embedded item attachment.
     
    That can be cast to whatever actual type (RDOContact, RDOAppointment, etc.) or left as RDOMail (more or less an IMessage), and Redemption can be used from C#.

    --
    Ken Slovak
    MVP - Outlook
    http://www.slovaktech.com
    Author: Professional Programming Outlook 2007
     
     
    "Scott-ATX" <=?utf-8?B?U2NvdHQtQVRY?=> wrote in message news:69917ced-ee34-4222-8873-cf91cf06a770...

    Oops, you're right.  My bad.

    Thanks again for your feedback.

    I've found some more info on this particular issue and it looks like there are some C++ solutions but no other workaround in C# (except for saving to disk option as mentioned).  Also, Was researching if perhaps I could get entryID and pull it that way, but apparently embedded attachments have their entry ID stripped.

    For anyone else researching this, here is a related writeup:  http://msdn.microsoft.com/en-us/library/cc842411.aspx 

    And for folks that want to use my example above, here is some additional info:

    using Microsoft.SharePoint.Client;
    using ClientOM = Microsoft.SharePoint.Client;
    using System.IO;
    using System.Net;

    And, a working input format for clientcontentURL and sitelibfolder is specifically:

    http://moss.blah.com     and       /sites/SITENAME/Shared Documents/subfoldername/


    Ken Slovak MVP - Outlook
    Thursday, March 1, 2012 7:03 PM
    Moderator
  • Hi Scott,

    I do have a similar requirement in the project which i was working on.

    Can you please provide me the source code for the the save configuration part.

    Can you please help me in this.

    Thanks,

    Swaroop V

    Thursday, May 17, 2012 11:25 AM