none
[E2010] [EWSMA] [C#]: PROBLEM: Retrieving Extended Properties from a Shared Message Item? RRS feed

  • Question

  • All I want to do at this point is READ some extended property definitions that are supposed to be there (according to the documents I have been reading on the Exchange Messaging Protocol Specifications regarding Shared Message Objects and Invitation messages.

    Ultimately this is what I’ve been able to piece together from various sources, and from what I understand this should be working but I’m not getting any values returned? 

    Here’s the setup:

     

    Language:                                        C#

    Exchange Version:                          2010 SP1

    WebServices Proxy:                       EWS Managed API 1.2

    Impersonation:                               I have an account with impersonation setup so I can use impersonation                                                         on any account to be able to manipulate permissions, etc. & it works                                                         great in those respects.

    I have a “plugin” class I found to use for doing a “quickcheck” :

    // Reference: http://www.infinitec.de/category/Exchange-articles.aspx?page=2
    
    public static class ItemExtension
    
     { 
    
        public static T GetValueOrDefault<T>(this Item item, PropertyDefinitionBase property, T defaultValue = default(T))
    
            {
    
                T result;
    
                return item.TryGetProperty(property, out result) ? result : defaultValue;
    
            } 
    
        }


    Now here’s the part where I click a button, and I get a list of all normal properties, but the extended properties I’m trying to retrieve always come back with “notfound” (*note* I had to put a default value for out or it would come back with a nullreferenceexception):

               ExchangeService service = GetExchangeService();
    
                service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, txtImpersonatedUser.Text.ToString());
    
     
    
                // LOAD OUR CUSTOM PROPERTIES
                Guid PropertySetSharing = new Guid("{00062040-0000-0000-C000-000000000046}");
    
                Guid PropertySetInternetHeaders = new Guid("{00020386-0000-0000-C000-000000000046}");
        
                // Sharing Properties (according to protocol examples in: [MS-OXSHARE])
    
                ExtendedPropertyDefinition PidNameContentClass = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "Content-Class", MapiPropertyType.String);
    
                ExtendedPropertyDefinition PidNameXSharingFlavor = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Flavor", MapiPropertyType.String); 
    
                ExtendedPropertyDefinition PidLidSharingInitiatorEntryId = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A09, MapiPropertyType.Binary);
              
                ExtendedPropertyDefinition[] extendedProps = new ExtendedPropertyDefinition[] {
    
                 PidNameContentClass,
                 PidNameXSharingFlavor,
                 PidLidSharingInitiatorEntryId
            
    
                };
    
     
    
                  // Define the property set to use in result sets
    
                PropertySet ps = new PropertySet(BasePropertySet.FirstClassProperties,extendedProps);
    
                  // Bind to the Sent items folder, where there is only one item that was a sharing
                  // invitation I sent to another account via OWA.  I figured that item would be the
                  // item I wanted to check for these special extended properties for, since you can
                  // set them using SetExtendedProperty() when creating message objects.
    
                var folder = Folder.Bind(service, WellKnownFolderName.SentItems);
          
                // In the view below I assign the propertyset ps to it as well as set
                // the Traversal to shallow.  I have tried associated here as well but
                // instead of getting the regular properties but no extended ones, I get         // nothing at all!
    
                var myView = new ItemView(512)
                {
    
                    Traversal = ItemTraversal.Shallow,
                    PropertySet = ps
    
                };
    
                  // I filter the search by IPM.Sharing so in case for some reason this test account
    
                  // sends out another email (right now theres only one item in sent items)
    
                SearchFilter mySearchFilter = new SearchFilter.IsEqualTo(ItemSchema.ItemClass, "IPM.Sharing");
    
     
    
                FindItemsResults<Item> results = folder.FindItems(mySearchFilter, myView);
    
                 
    
                  // Here I can get all the properties from GetLoadedPropertyDefinitions ok
    
                foreach (var item in results)
    
                {
    
                    foreach (PropertyDefinitionBase propertyItem in item.GetLoadedPropertyDefinitions())
    
                    {
    
                        listBox1.Items.Add(propertyItem.ToString()+ ":(" + propertyItem.Type.Name.ToString() + "): ");
    
                    }
    
                         // I don’t know if this is redundant or necessary but Load the whole properset
                         // because attempts without it were not doing anything either
    
                        item.Load(ps);
    
     
    
                       // This is where I use the extension class to check the existence of the                 
                       // extended properties that I defined and searched for.  But nothing ever comes          
                       // back.  Am I looking at the right object for these properties or is there          
                      // something else? I know there is an attachment object too but I’ll deal with 
                      // that separately.  Am I not defining the property sets or search filters properly?
    
                        listBox1.Items.Add("SharingFlavor: " + item.GetValueOrDefault<string>(PidNameXSharingFlavor, "notfound"));
    
                        listBox1.Items.Add("NameContentClass: " + item.GetValueOrDefault<string>(PidNameContentClass, "notfound"));
    
                        listBox1.Items.Add("InitiatorEntryId: " + item.GetValueOrDefault<string>(PidLidSharingInitiatorEntryId, "notfound"));
    
                   
    
                }
    
     
    
     
    
                service.ImpersonatedUserId = null;
    
     
    

    I've been at this for the last 3 days (and I'm supposed to be on vacation! This is supposed to be FUN!!!) but I'm completely stuck.  Show me the error of my ways!!!!

    Thanks for any feedback, input in advance!

     

     

     

     

     

     

     

     

     

     

     

    Tuesday, April 10, 2012 3:40 AM

Answers

  • Okay your code works for me when i query against a normal Sharing invitation what i would suggest is you look at the Items in the SentItems folder of the Mailbox your querying with a Mapi Editor like MFCMapi or OutlookSpy have a look at the Item your getting the response for and you should be able to see any of the properties that have been set on that Item which is pretty much what you can query. Eg you should see properties like (this is from OutlookSpy)

    The other thing you could do just as a test is put in a simple Extended Property that you know will always get returned like the Subject just to make sure its not some weird bug (given that your not using the latest Sp for Exchange 2010 eg your at sp1 ru5) although I think its unlikely the issue.

    ExtendedPropertyDefinition Pr_Subject = new ExtendedPropertyDefinition(0x0037, MapiPropertyType.String);

    Cheers
    Glen

    Tuesday, April 10, 2012 6:17 AM

All replies

  • What's happening when I run your code is all those Extended properties are returned but the Extended property PropSet GUID for PidNameContentClass and PidNameXSharingFlavor are geting resolved the default Enum DefaultExtendedPropertySet.InternetHeader which is causing the TryGet to fail. Also with PidLidSharingInitiatorEntryId the returned GUID's case is lower which again causes the TryGet to fail because your GUID def is Upper

    try these instead which should fix the issue 

                Guid PropertySetSharing = new Guid("{00062040-0000-0000-c000-000000000046}");
    
                ExtendedPropertyDefinition PidNameContentClass = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.InternetHeaders, "Content-Class", MapiPropertyType.String);
                ExtendedPropertyDefinition PidNameXSharingFlavor = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.InternetHeaders, "X-Sharing-Flavor", MapiPropertyType.String);
                ExtendedPropertyDefinition PidLidSharingInitiatorEntryId = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A09, MapiPropertyType.Binary);  

    You dont need item.Load(ps); as these propertis will be returned okay in the FindItems call

    Cheers
    Glen


    Tuesday, April 10, 2012 4:38 AM
  • Thanks for the reply Glen, I've been reading a lot of your posts and others' regarding this subject so I hope to eliminate any worthless typos, but the case sensitivity thing makes sense (but I was unaware it was an issue!), as does the DefaultExtendedPropertySet.InternetHeaders piece..

    Now I've changed the code, but I'm still not getting results....the values for the extendedproperties still come back with nothing

    Here's the modified code, which I narrowed further in scope for troubleshooting purposes to take out as many possible variables that could still cause the FailRetry:

     Guid PropertySetSharing = new Guid("{00062040-0000-0000-c000-000000000046}");
    
    ExtendedPropertyDefinition PidNameContentClass = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.InternetHeaders, "Content-Class", MapiPropertyType.String);
    ExtendedPropertyDefinition PidNameXSharingFlavor = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.InternetHeaders, "X-Sharing-Flavor", MapiPropertyType.String);
               
    ExtendedPropertyDefinition[] extendedProps = new ExtendedPropertyDefinition[] { 
                 PidNameContentClass,
                 PidNameXSharingFlavor
                
                };
                    PropertySet ps = new PropertySet(BasePropertySet.FirstClassProperties, extendedProps);
    
                    var folder = Folder.Bind(service, WellKnownFolderName.SentItems);
    
    
                    var myView = new ItemView(512)
                    {
                        // Is the traversal the issue maybe??
                        Traversal = ItemTraversal.Shallow,
                        PropertySet = ps
                    };
    
                    SearchFilter mySearchFilter = new SearchFilter.IsEqualTo(ItemSchema.ItemClass, "IPM.Sharing");
    
                    FindItemsResults<Item> results = folder.FindItems(mySearchFilter, myView);
                    
                    foreach (var item in results)
                    {
                         
                        foreach (PropertyDefinitionBase propertyItem in item.GetLoadedPropertyDefinitions())
                        {
                            listBox1.Items.Add(propertyItem.ToString() + ":(" + propertyItem.Type.Name.ToString() + "): " );
                        }
                        foreach (ExtendedProperty extendedProperty in item.ExtendedProperties)
                        {
                            listBox1.Items.Add("Extended Property Name: " + extendedProperty.PropertyDefinition.Name);
                            listBox1.Items.Add(" Extended Property Value: " + extendedProperty.Value);
                        }
                        //item.Load(ps);
                        listBox1.Items.Add("SharingFlavor: " + item.GetValueOrDefault<string>(PidNameXSharingFlavor));
                        listBox1.Items.Add("NameContentClass: " + item.GetValueOrDefault<string>(PidNameContentClass));
                        
                        // Display the name and value of the extended property.
                        object itemOut;
                        if (item.TryGetProperty(PidNameXSharingFlavor, out itemOut))
                        {
                            listBox1.Items.Add(itemOut.ToString());
                        }
                 }

    If it helps this is the SOAP Request I send: (captured by trace)

    <Trace Tag="EwsRequest" Tid="1" Time="2012-04-10 05:32:01Z" Version="14.03.0032.000">
      <?xml version="1.0" encoding="utf-8"?>
      <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
        <soap:Header>
          <t:RequestServerVersion Version="Exchange2010_SP1" />
          <t:ExchangeImpersonation>
            <t:ConnectingSID>
              <t:SmtpAddress>IMPERSONATEDEMAILADDRESS</t:SmtpAddress>
            </t:ConnectingSID>
          </t:ExchangeImpersonation>
        </soap:Header>
        <soap:Body>
          <m:FindItem Traversal="Shallow">
            <m:ItemShape>
              <t:BaseShape>AllProperties</t:BaseShape>
              <t:AdditionalProperties>
                <t:ExtendedFieldURI DistinguishedPropertySetId="InternetHeaders" PropertyName="Content-Class" PropertyType="String" />
                <t:ExtendedFieldURI DistinguishedPropertySetId="InternetHeaders" PropertyName="X-Sharing-Flavor" PropertyType="String" />
              </t:AdditionalProperties>
            </m:ItemShape>
            <m:IndexedPageItemView MaxEntriesReturned="512" Offset="0" BasePoint="Beginning" />
            <m:Restriction>
              <t:IsEqualTo>
                <t:FieldURI FieldURI="item:ItemClass" />
                <t:FieldURIOrConstant>
                  <t:Constant Value="IPM.Sharing" />
                </t:FieldURIOrConstant>
              </t:IsEqualTo>
            </m:Restriction>
            <m:ParentFolderIds>
              <t:FolderId Id="AAMkADc0ODI1MTFiLWJkY2YtNDk2My1hMjMxLWIzMjM5YzgyNGFkMAAuAAAAAADqJyxjh6mUQrSzcaGJBeTbAQB/hhbjrJOlR6mhsPJJtkkbAAAAJHwEAAA=" ChangeKey="AQAAABYAAAB/hhbjrJOlR6mhsPJJtkkbAAAEQj3X" />
            </m:ParentFolderIds>
          </m:FindItem>
        </soap:Body>
      </soap:Envelope>
    </Trace>
    

    Here's the response (notice the lack of extended properties returned):

    <Trace Tag="EwsResponse" Tid="1" Time="2012-04-10 05:32:02Z" Version="14.03.0032.000">
      <?xml version="1.0" encoding="utf-8"?>
      <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
        <s:Header>
          <h:ServerVersionInfo MajorVersion="14" MinorVersion="1" MajorBuildNumber="339" MinorBuildNumber="1" Version="Exchange2010_SP1" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
        </s:Header>
        <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
          <m:FindItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
            <m:ResponseMessages>
              <m:FindItemResponseMessage ResponseClass="Success">
                <m:ResponseCode>NoError</m:ResponseCode>
                <m:RootFolder IndexedPagingOffset="1" TotalItemsInView="1" IncludesLastItemInRange="true">
                  <t:Items>
                    <t:Message>
                      <t:ItemId Id="AAMkADc0ODI1MTFiLWJkY2YtNDk2MyhG8AAA=" ChangeKey="CQAAABYAAAB/hhbjrJOlR6mhsPJJtkkbAAAEQhO8" />
                      <t:ParentFolderId Id="AAMkAEAAA=" ChangeKey="AQAAAA==" />
                      <t:ItemClass>IPM.Sharing</t:ItemClass>
                      <t:Subject>I'd like to share my calendar with you</t:Subject>
                      <t:Sensitivity>Normal</t:Sensitivity>
                      <t:DateTimeReceived>2012-03-30T18:28:25Z</t:DateTimeReceived>
                      <t:Size>2916</t:Size>
                      <t:Importance>Normal</t:Importance>
                      <t:IsSubmitted>false</t:IsSubmitted>
                      <t:IsDraft>false</t:IsDraft>
                      <t:IsFromMe>false</t:IsFromMe>
                      <t:IsResend>false</t:IsResend>
                      <t:IsUnmodified>true</t:IsUnmodified>
                      <t:DateTimeSent>2012-03-30T18:28:25Z</t:DateTimeSent>
                      <t:DateTimeCreated>2012-03-30T18:28:02Z</t:DateTimeCreated>
                      <t:DisplayCc />
                      <t:DisplayTo>SharedToUser</t:DisplayTo>
                      <t:HasAttachments>true</t:HasAttachments>
                      <t:Culture>en-US</t:Culture>
                      <t:EffectiveRights>
                        <t:CreateAssociated>false</t:CreateAssociated>
                        <t:CreateContents>false</t:CreateContents>
                        <t:CreateHierarchy>false</t:CreateHierarchy>
                        <t:Delete>true</t:Delete>
                        <t:Modify>true</t:Modify>
                        <t:Read>true</t:Read>
                        <t:ViewPrivateItems>true</t:ViewPrivateItems>
                      </t:EffectiveRights>
                      <t:LastModifiedName>SharedByUser</t:LastModifiedName>
                      <t:LastModifiedTime>2012-03-30T18:28:25Z</t:LastModifiedTime>
                      <t:IsAssociated>false</t:IsAssociated>
                      <t:WebClientReadFormQueryString>?ae=Item&amp;a=Open&amp;t=IPM.Sharing&amp;id=RgAAAA&amp;exvsurl=1</t:WebClientReadFormQueryString>
                      <t:ConversationId Id="AAQkADc0ODI1MTFiLWJkY2Y5L/NJHtlM=" />
                      <t:Sender>
                        <t:Mailbox>
                          <t:Name>SharedByUser</t:Name>
                          <t:MailboxType>OneOff</t:MailboxType>
                        </t:Mailbox>
                      </t:Sender>
                      <t:IsReadReceiptRequested>false</t:IsReadReceiptRequested>
                      <t:IsDeliveryReceiptRequested>false</t:IsDeliveryReceiptRequested>
                      <t:ConversationIndex>Ac0Oostcpul/kpZdfdsfDF80ke2Uw==</t:ConversationIndex>
                      <t:ConversationTopic>I'd like to share my calendar with you</t:ConversationTopic>
                      <t:From>
                        <t:Mailbox>
                          <t:Name>SharedByUser</t:Name>
                          <t:MailboxType>OneOff</t:MailboxType>
                        </t:Mailbox>
                      </t:From>
                      <t:InternetMessageId>&lt;7FSDEFDFDF547A9A1B0F249B6491B04420FAE@SERVER.FQDN.EXT&gt;</t:InternetMessageId>
                      <t:IsRead>true</t:IsRead>
                    </t:Message>
                  </t:Items>
                </m:RootFolder>
              </m:FindItemResponseMessage>
            </m:ResponseMessages>
          </m:FindItemResponse>
        </s:Body>
      </s:Envelope>
    </Trace>
    

    Tuesday, April 10, 2012 5:48 AM
  • Okay your code works for me when i query against a normal Sharing invitation what i would suggest is you look at the Items in the SentItems folder of the Mailbox your querying with a Mapi Editor like MFCMapi or OutlookSpy have a look at the Item your getting the response for and you should be able to see any of the properties that have been set on that Item which is pretty much what you can query. Eg you should see properties like (this is from OutlookSpy)

    The other thing you could do just as a test is put in a simple Extended Property that you know will always get returned like the Subject just to make sure its not some weird bug (given that your not using the latest Sp for Exchange 2010 eg your at sp1 ru5) although I think its unlikely the issue.

    ExtendedPropertyDefinition Pr_Subject = new ExtendedPropertyDefinition(0x0037, MapiPropertyType.String);

    Cheers
    Glen

    Tuesday, April 10, 2012 6:17 AM
  • Thanks for the tips Glen,

    Ok so the control reference (PR_Subject) totally came back and when I'm looking at the properties through outlook spy the ones I'm looking for (like x-sharing-capabilities) return a MAPI error so I'm thinking it's one of two things:

    1) Could it be that since I generated the Invitation through OWA instead of the outlook client there are certain properties that don't get populated when I generate the invite?

    or

    2) The weird bug thing you mentioned due to my Exchange Version (as you said, SP1 RU5)

    I will try generating another invitation and see if I run into the same problem when trying to enumerate that item's extended properties...and if that doesn't work I'll use a different account to make sure its not related to the mailbox itself...

    In either case thanks for double-checking my code I can at least rest easier knowing that the code is sound...it's just something else that's causing the issue.

    Thanks again!

    Tuesday, April 10, 2012 8:56 PM
  • 1) Yep I don't why but if you do it via OWA none of those extended properties are created and only the sharing_metadata.xml attachment is availble.

    I'm not sure what your trying to use those extended props for ? you might want to look at the content of the sharing_metadata.xml to see if it contains the information you need.

    Cheers
    Glen

    Wednesday, April 11, 2012 5:39 AM
  • Ok thanks for the tips Glen, I think I'm on the right track!!!

    My XML document which I thought was byte for byte was actually 6 bytes off (looking into that as we speak)

    When I did everything the same except attach the XML from my control message the invite worked without a hitch.

    Thanks for your patience and help through this!!! I think I'm gonna write a blog post about this experience soon, and I couldn't have gotten through it without your blog and your help here...thanks again!!!

    Mike

    Friday, April 13, 2012 10:33 PM