none
Custom properties added by EWS not visible in Outlook

    Question

  • Hi all
    I'm a first-time Exchange and Outlook addin developer and I'm stuck on a problem.

    I'm working on a project where we use an Outlook 2003 addin that tags items; mail, appointments and tasks
    with custom properties.

    In Outlook we do this by adding the data as UserProperties.
    After the items have been saved an onsave eventSink triggers on the Exchange 2007 mailbox server and using CDOEX, checks for the tags, collects some data and sends them to an web service wich stores the data on an AX server.
    This works fine.

    Then we want the AX server to be able to update and create new items back against exchange, and for this we use Exchange Web Services.
    I've made an application that performs the operations agains EWS, and everything works smoothly except when we add the custom properties.
    We add them as extendedproperties with the following code:

    ExtendedPropertyType extendedProperty = new ExtendedPropertyType();
    extendedProperty.ExtendedFieldURI = new PathToExtendedFieldType();
    extendedProperty.ExtendedFieldURI.DistinguishedPropertySetId = DistinguishedPropertySetType.PublicStrings;
    extendedProperty.ExtendedFieldURI.DistinguishedPropertySetIdSpecified = true;
    extendedProperty.ExtendedFieldURI.PropertyName = propertyName;
    extendedProperty.ExtendedFieldURI.PropertyType = MapiPropertyTypeType.String;
    extendedProperty.Item = propertyValue;

    This worked well for the eventSink, we found the fields and got the values just like we did for items tagged by the Outlook addin.

    However, the Outlook Addin could not find them in the UserProperties object for the item, and Using Outlookspy I could plainly see that they were not present.

    After a bunch of searching I found a thread on this forum that discussed adding custom properties as ExtendedPropertyTypes via EWS using a guid as a PropertySetType.
    Here it is: http://forums.microsoft.com/technet/showpost.aspx?postid=1764780&siteid=17

    I followed the instructions here, and now both the eventSink and Outlook are unable to find the properties.

    My question is:
    How can I apply my tags so both my Outlook addin and EWS can create, update and read them, as well as allowing the eventSink to easily read them?
    The simplest way, I imagine, is if I could make Exchange Web Services place the properties in the "UserProperties" object.

    I would greatly appreciate any help.

    thanks
    Ragnar Fatland


    Wednesday, November 21, 2007 5:00 PM

Answers

  • Per those that know infinitely more about Outlook than I do:

     

    A “User Property” is Outlook’s way of handling custom properties in the UI and the object model. They’re implemented at the MAPI layer as named properties in the PS_PUBLIC_STRINGS namespace, so in that sense they’re identical to regular MAPI named properties. But, Outlook tracks them in a data blob stored in another property. This data blob, which, btw, is not  trivial to parse, tells Outlook which user props have been “registered” in a folder or on an item. If a named prop is tracked in the blob, then Outlook can/will show it in its UI. If it’s not tracked in the blob, the UI won’t show the prop.

     

    So – a developer who wants their custom props to show in the UI will want to use outlook’s “user properties”. Right now, that means they need to use the Outlook Object Model to define the properties. Once the props are defined, they can manipulate them with any API that handles named props (OOM, MAPI, EWS, etc).

     

     

    Hope that helps Smile

     

    Tuesday, November 27, 2007 3:11 PM

All replies

  • You show the code for creating the extended property, but could you also include the code for how you set it on the item?  I assume that this is an UpdateItem call?  Also, what happens if you immediately turn around and call GetItem on the updated item and request those custom props - does EWS see them?

     

    Also, when you are updating the item, are you checking for a failure response code in the corresponding response message?

     

    Thursday, November 22, 2007 12:24 PM
  • I'm trying for both UpdateItem and CreateItem.

    I get succsess in the response message, and as mentioned the fields can be accessed by my coworker's CDOEX-based application, which collects them from the CDOEX messageobject's "Fields" collection.

    When I call GetItem on the item I've created or updated, I get the extendedProperty fields as normal.

    Here is my code for setting them on the object during a createItem operation, I have an attemt at :

    private static ExtendedPropertyType createCommonExtendedProperty(String propertyName, String propertyValue)
    {
    ExtendedPropertyType extendedProperty = new ExtendedPropertyType();
    extendedProperty.ExtendedFieldURI = new PathToExtendedFieldType();
    extendedProperty.ExtendedFieldURI.DistinguishedPropertySetId = DistinguishedPropertySetType.PublicStrings;
    extendedProperty.ExtendedFieldURI.DistinguishedPropertySetIdSpecified = true;
    extendedProperty.ExtendedFieldURI.PropertyName = propertyName;
    extendedProperty.ExtendedFieldURI.PropertyType = MapiPropertyTypeType.String;
    extendedProperty.Item = propertyValue;
    return extendedProperty;
    }

    // is called by

    private static ExtendedPropertyType[] createCommonCustomProperties(String[] custProp)
    {
    ExtendedPropertyType[] customProperties = new ExtendedPropertyType[custProp.Length];
    customProperties[0] = createCommonExtendedProperty("AXID", custProp[0]);
    customProperties[1] = createCommonExtendedProperty("BusRelId", custProp[1]);
    customProperties[2] = createCommonExtendedProperty("ContactId", custProp[2]);
    customProperties[3] = createCommonExtendedProperty("ProjId", custProp[3]);
    customProperties[4] = createCommonExtendedProperty("QuotationId", custProp[4]);
    return customProperties;
    }

    // which is called by the common field creator, the "EWS..." objects are my own stripped-down objects used for shipping data around...

    private static void createCommonFields(ItemType newItem, EWSItemBase newEWSItem)
    {
    // Sets a bunch of different common fields for item ...
    newItem.ExtendedProperty = createCommonCustomProperties(newEWSItem.CustProp);
    //...
    }
    private static String createCalendarItem(ExchangeServiceBinding service, EWSCalendarItem newCalendarItem, CalendarItemCreateOrDeleteOperationType sendMeetingInvitations)
    {
    // Set up the new Calendar
    CalendarItemType newCalendar = new CalendarItemType();

    // Create Common Fields
    createCommonFields(newCalendar, newCalendarItem);

    // Create Calendar Specific Fields
    createCalendarFields(newCalendar, newCalendarItem);
    // Create and populate the request
    CreateItemType createItemRequest = new CreateItemType();
    // Set user and folder
    createItemRequest.SavedItemFolderId = new TargetFolderIdType();
    createItemRequest.SavedItemFolderId.Item = setCommonUserFolder(newCalendarItem.ItemId.UserEmailAdress, DistinguishedFolderIdNameType.calendar)[0];
    // Add the calendar item to the request
    createItemRequest.Items = new NonEmptyArrayOfAllItemsType();
    createItemRequest.Items.Items = new ItemType[1];
    createItemRequest.Items.Items[0] = newCalendar;
    // Set request parameters
    createItemRequest.MessageDisposition = MessageDispositionType.SaveOnly;
    createItemRequest.MessageDispositionSpecified = true;
    // Set meeting invitation mode
    createItemRequest.SendMeetingInvitations = sendMeetingInvitations;
    createItemRequest.SendMeetingInvitationsSpecified = true;
    CreateItemResponseType createItemResponse = null;
    // send the request and receive the response
    try
    {
    createItemResponse = service.CreateItem(createItemRequest);
    }
    catch(SoapException ex)
    {
    return "Error:" + ex.Message + "\n" + ex.Detail.InnerText;
    }
    ResponseClassType responseClass = createItemResponse.ResponseMessages.Items[0].ResponseClass;
    String response = responseClass.ToString();

    return response;
    }

    As far as I've understood from various sources, MAPI's PS_PUBLIC_STRING, Outlook's Item.UserProperties
    and EWS's DistinguishedPropertySetType.PublicStrings are all pointing to the same store, so in (my) theory I shouldn't be experiencing the problem unless there is some sort of bug somewhere...


    Thursday, November 22, 2007 3:48 PM
  • I've tested a lot more and I have to correct myself:

    There are two cases where this works:

    1. If i manually create an item in Outlook and tag it using my outlook addin, (which uses item.UserProperties.Add(...)) and then update the item with EWS with the code described above.
    2. An item created by EWS, is tagged by the Outlook addin, the tags set by the addin, and all future updates from EWS are visible, but whatever EWS set during creation is only visible to EWS prior to the update form Outlook.

    Basically this means that the tags are not available in Outlook before they have been set by the Outlook addin.

     

    Outlook takes a long time to show the updates to the tags and even loads all the other updates to the item before I see the change in the tags. Restarts of Outlook, forced updates and running Outlook in cached and non-cached exchange mode did nothing to remedy this.

    This lag in the updates lead to my previous misunderstanding that nothing was accessible.

     

    The case that I want/need to work is:

    1. Creating an tagged item with EWS, and having the tags immidiatly accessible in Outlook.
      • Problem: The tags are available to EWS and our eventSink, but not in Outlook.
      • Is there some property that I must set for it to work ?

    I would REALLY appreciate some answers to this issue.

     

    Thanks,

    Ragnar

    Monday, November 26, 2007 1:54 PM
  • Sounds like OL is setting some super duper property somewhere that changes how OL views those user props.  Let me ping some other folks internally as I am not an OL dev.

     

    Monday, November 26, 2007 2:06 PM
  • Thanks, that would be great Smile
    Tuesday, November 27, 2007 11:22 AM
  • Per those that know infinitely more about Outlook than I do:

     

    A “User Property” is Outlook’s way of handling custom properties in the UI and the object model. They’re implemented at the MAPI layer as named properties in the PS_PUBLIC_STRINGS namespace, so in that sense they’re identical to regular MAPI named properties. But, Outlook tracks them in a data blob stored in another property. This data blob, which, btw, is not  trivial to parse, tells Outlook which user props have been “registered” in a folder or on an item. If a named prop is tracked in the blob, then Outlook can/will show it in its UI. If it’s not tracked in the blob, the UI won’t show the prop.

     

    So – a developer who wants their custom props to show in the UI will want to use outlook’s “user properties”. Right now, that means they need to use the Outlook Object Model to define the properties. Once the props are defined, they can manipulate them with any API that handles named props (OOM, MAPI, EWS, etc).

     

     

    Hope that helps Smile

     

    Tuesday, November 27, 2007 3:11 PM
  •  David Sterling - MSFT wrote:

     

    So – a developer who wants their custom props to show in the UI will want to use outlook’s “user properties”. Right now, that means they need to use the Outlook Object Model to define the properties. Once the props are defined, they can manipulate them with any API that handles named props (OOM, MAPI, EWS, etc).

     

     

    Hope that helps



    Thanks, it helps in a way Wink
    It confirms my suspicions in that it is currently impossible to create "UserProperties" which are accessible to the Outlook Object model/GUI from Exchange Web Services, and that this would have to be handled by something else.

    I imagine a possible workaround would be to let the Outlook addin access PS_PUBLIC_STRINGS in the MAPI object through one of the third-parrty librarys such as Outlook Redemption (which I considered earlier on), search for the properties and then automatically create the UserProperties whenever an Item was received or opened.

    Do you have any plans to support this in EWS at a future date ? Or will it be considered an Outlook issue to be remedied in a future version?

    Anyway, thanks for your answer Smile

    Ragnar
    Tuesday, November 27, 2007 4:05 PM
  • Honestly, I am not sure if that will be handled at a later time or not (parsing in EWS).  OL is certainly a great Exchange client application, but is certainly not the only one.  These OL blobs contain semantics that are peculiar to OL.  In other words, Exchange doesn't have any use for such blobs - it just stores them for the client.  You can write your own client app that stores your own super-special binary data in an extended property, but if other client apps want to user your binary data, they must be privy to how such data is serialized, etc...

     

    In general, binary data that Exchange itself acts on (calendar recurrence blobs, search folders, etc...) is parsed and presented in a more usable format.  However, Outlook "user properties" don't fall into that camp. 

     

    Again, that is just my opinion.  If my manager tells me tomorrow to surface OL user prop manipulation through EWS, then indeed things will be different Smile

     

     

     

     

    Tuesday, November 27, 2007 4:17 PM
  • David,

    I have the same issue and was wondering if changing the calendar schema to add the "extended property" would solve this issue? I am coding the same way pushing calendar items to exhcange and then viewing them in outlook 2007. I have a property I am trying to view and of course it is not showing up despite referencing it using the following namespace format http://schemas.microsoft.com/mapi/string/{HHHHHHHH-HHHH-HHHH-HHHH-HHHHHHHHHHHH}/name to access my extended property from the PropertyAccessor.GetProperty call.

     

     

    Thursday, January 31, 2008 7:29 PM
  • Dave,

    I have noticed that CDO, OWA, 2007's Calendar Attendant are also not aware of these "User Properties" and will not copy them from a meeting request message to the calendar event.

     

    So, for all practical purposes, are these properties usable only with the Outlook client, and if Exchange 2007 is the backend, then automated processing of meeting requests must be turned off?

    Friday, February 01, 2008 8:37 PM
  • I'm sorry but I can't believe that this would be any type of acceptable answer to for any Microsoft Partner/ISV that creates or extends the functionality of Outlook.  We have just uncovered a HUGE problem with our custom Outlook solution.  We put custom properties on Outlook appointments and meetings  via an add-in in Outlook. When the attendees of a meeting accept the meeting request, their copy of the meeting item contains the custom properties as well, which is necessary for our solution to work properly.  With the introduction of the Calendar Attendant in Exchange 2007 our solution will not function properly because when the attendant automatically creates the calendar item for the user and marks it tentative, none of the custom mapi properties are put on the message.  Even when the recipient accepts the meeting request from the inbox the custom properties do not make it onto the appointment item.  This is a huge problem.  

    If we turn off the calendar attendant functionality the problem goes away because when the meeting request is accepted by the recipient in Outlook the appointment item is created correctly.

    This basically means that any vender that is relying on custom properties can not make use of the Calendar attendant and must have their clients disable it.

     

    So, my question is this....when the appointment item is put on the user's calendar by the calendar attendant why doesn't it just transfer over any/all MAPI properties that exist on the MAPI message? 

    Thursday, May 29, 2008 11:00 PM
  • Ragnar,
    I have same problem which the User Property added to new created calendar item which can't be viewed from Outlook.  Could you please let me know if you have any work around for this issue.

    Thanks.

    David

    Tuesday, December 23, 2008 1:57 AM
  • Hi,

    After reading this forum, will this case work:

    1. Create custom property from Outlook AddIn (using item.UserProperties.Add(...)).

    2. Can this custom property now be accessed (I just need to read it (not modify/delete)) from EWS?

    Thanks

     

    Friday, February 18, 2011 1:35 AM
  • Hi,

    I got this part working (Outlook AddIn inserting user properties and accessing them via EWS).

     

    Thanks for all the information on this forum page.

     

    Thursday, February 24, 2011 12:36 AM
  • Hi there. Can you explain a bit more about how did you achieve this ? 

    I was using MAPI interface and now thinking of moving to EWS. So doing some pre researching .

    Did you mean that you added userProperties using outlook and accessed them using EWS ? 

    Thanks

    Friday, April 15, 2011 2:21 PM
  • Hi I have extended property definition like this:

    string guid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
    Guid MY_PROPERTY_SET_GUID = new Guid(guid);
    ExtendedPropertyDefinition MyExPropDef = new ExtendedPropertyDefinition(
    			MY_PROPERTY_SET_GUID, "MyExPropName", MapiPropertyType.String);


    Then  I have object of Microsoft.Exchange.WebServices.Data.Appointment type and I can set it's extended property value with EWS Managed API:

    appointment.SetExtendedProperty(MyExPropDef,"myStringValue");


    In Outlook AddIn I can set this property this way:

    string schema = "http://schemas.microsoft.com/mapi/string/{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}/MyExPropName";
    
    appointment.PropertyAccessor.SetProperty(schema,value);
    

    When I change the property set from MY_PROPERTY_SET_GUID to DefaultExtendedPropertySet.PublicStrings, then I am able to assign property value in Oulook AddIn and access it via EWS. With MY_PROPERTY_SET_GUID it is not working, why?

    Wednesday, August 17, 2011 11:06 AM
  • Hello David,

    do you know whether this scenario still applies to Exchange 2013 / Office 2013?

    Or is it possible to create extended properties with EWS (e.g. for contacts) and make them visible in Outlook in the meantime?

    I would greatly appreciate any help.

    Thanks,

    Dennis  

    Saturday, December 07, 2013 3:55 PM
  • I first created an extended property:

    ExtendedPropertyDefinitionepdGuid =

    newExtendedPropertyDefinition(

    DefaultExtendedPropertySet.PublicStrings, "Guid", MapiPropertyType.String);

    Then I setup the service:

    ExchangeServiceservice = newExchangeService(ExchangeVersion.Exchange2010_SP2);

    Find all the items:

    FindItemsResults<Item> userItems = service.FindItems(newFolderId(WellKnownFolderName.Inbox, userMailbox),

    newItemView(int.MaxValue, 0)

        {

            PropertySet =

    newPropertySet(BasePropertySet.FirstClassProperties, epdGuid)

        });

    Loop through the userItems:

    foreach(varitem inuserItems)

    {

    if(item isEmailMessage)

    {

    EmailMessagemessage = item asEmailMessage;

    Do a message load with the PropertySet (if you don't do the PropertySet you won't see any extended properties):

    message.Load(

    newPropertySet(epdGuid));

    Then you can loop through the extended properties:

    foreach(varextendedProperty inmessage.ExtendedProperties)

    {

    if(extendedProperty.PropertyDefinition.Name == "Guid")

                                        {




    Wednesday, April 02, 2014 3:47 PM