none
Why olOutlookInternal rather than olDateTime? RRS feed

  • Question

  • Many properties for Outlook items have a Type of enum Microsoft.Office.Interop.Outlook.OlUserPropertyType. Fields like Anniversary and Birthdate have a Type of olOutlookInternal, not olDateTime. Why is that?

    Thanks!

    Sunday, July 8, 2012 11:53 PM

All replies

  • HI Starbuck,

    Thanks for posting in the MSDN Forum.

    I'm wondering how you get the type of "Anniversary" and "Birthdate". I tried to look these field in MAPI, and found they are PT_SYSTIME, it means that they are olDateTime in Microsoft.Office.Interop.Outlook.OlUserPropertyType.

    Have a good day,

    Tom


    Tom Xu [MSFT]
    MSDN Community Support | Feedback to us

    Monday, July 9, 2012 2:59 AM
    Moderator
  • Tom, thanks for your interest. I get the same kind of results with Contacts, Appointments, Journal items, and Tasks. I'm wondering if DateTime is reserved for fixed dates but olOutlookInternal is returned for dates which can be used for recurring events? (wild guess doesn't hold up)

    // hacked up example from my code
    olNameSpace = olApplication.GetNamespace("mapi");
    olNameSpace.Logon("Outlook", "", false, true);
    olFolder = olNameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
    olItems = olFolder.Items;
    foreach (object o in olItems)
       if (o is Outlook.ContactItem)
       {
           Outlook.ContactItem dataitem = (Outlook.ContactItem)o;
           Outlook.ItemProperties props = ((Outlook.ContactItem)dataitem).ItemProperties;
           foreach (Outlook.ItemProperty property in props)
           {
                switch (property.Type)
                {
                    case Microsoft.Office.Interop.Outlook.OlUserPropertyType.olInteger:
                    case Microsoft.Office.Interop.Outlook.OlUserPropertyType.olNumber:
                      // do stuff
                      break;
                    case Microsoft.Office.Interop.Outlook.OlUserPropertyType.olDateTime:
                      // some properties do show here
                      break;
                  case Microsoft.Office.Interop.Outlook.OlUserPropertyType.olOutlookInternal:
                     // Birthdate and Anniversary show up here
                     break;
    ...

    Monday, July 9, 2012 3:55 AM
  • I'm still wondering about the olOutlookInternal vs olDateTime thing, but this is my real goal...

    I'd like to be able to get the real CLR Type for Outlook (COM) items, but it's extremely difficult. Consider Outlook.ContactItem, an interface derived from _ContactItem. I've been trying to figure out how to use reflection on a ContactItem (interface) instance or the ContactItemClass to get PropertyInfo containing the actual CLR Types of each property. Because this is a COM interface, Type.GetProperties() doesn't return anything. I've even drilled into the flattened hierarchy of the interfaces and still get nothing.

    Can anyone tell me how to programmatically get the real types for each property in a Outlook.ContactItem or other item types?

    Example:

    Anniversary is DateTime
    AutoResolvedWinner is Boolean
    Body is String ...

    Why? Because I'm generating code which loads contact items with data from another environment, and I need to cast string data to the proper type in order to set each property. The generated code looks something like this:

    item.Anniversary = DateTime.Parse(data[CO_Anniversary]); // can't cast to olOutlookInternal...

    Thanks!

    Tuesday, July 10, 2012 7:52 PM
  • Hi Starbuck,

    I did some checking but was not able to find out exactly why this was implemented this way (If I recall correctly, ItemProperties was added back in Outlook 2003). It appears to be a limitation of how ItemProperties was implemented and we couldn't change it now if we wanted to because we'd break backwards compatibility with existing solutions.

    I believe the only workaround would be to avoid ItemProperties and explicitly refer to each of the properties, as in dataitem.Birthday.


    Bill Jacob - Microsoft Customer Service & Support - Developer Messaging

    Monday, July 16, 2012 8:45 PM
    Moderator
  • Bill, thanks for that response! For the reason you stated, I wouldn't ask for a mod in this area.

    My last note addresses your work-around. Can anyone comment on exactly how I would get the real data type for something like dataitem.Birthday, given the considerations I mentioned previously? My solution for now was to use VS2010, right click on ContactItem, Go To Definition, then copy that interface data to a new module and doctor it for my purposes. That's big-time sloppy. It would be much more elegant to use reflection or a similar process to iterate through the properties and acquire the Type programmatically.

    Thanks!

    Monday, July 16, 2012 9:24 PM
  • Why do you need reflection?

    If you do not know about a particular property, why do you need to touch it?


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.3 is now available!

    Monday, July 16, 2012 10:20 PM
  • Dmitry, from a recent note in this thread:

    Why? Because I'm generating code which loads contact items with data from another environment, and I need to cast string data to the proper type in order to set each property. The generated code looks something like this:

    item.Anniversary = DateTime.Parse(data[CO_Anniversary]); // can't cast to olOutlookInternal...

    I'm moving contacts, appointments, tasks, and perhaps journals between Outlook and another contact management system (CMS). I want to use strongly typed classes to do this properly. It's a mind-numbing exercise to manually ensure that all valid properties for each class/interface are typed properly with manually crafted casting. I would have preferred to have done this with code generation. The problem is that using ItemProperties to get the data type for many properties returns this olOutlookInternal type rather than the real type. I would much rather use something similar to reflection (issues with COM objects there) to use the property to get a real Type, then use Type.Name to generate my own class properties with correct typing.

    I hope that clarifies.

    Thanks!

    (Happy licensed Redemption user here)

    Monday, July 16, 2012 10:56 PM
  • But if you know the property name (Anniversary), you can use reflection to figure out the property type (DateTime), there is no reason to use the ItemProperties collection.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.3 is now available!

    Monday, July 16, 2012 11:01 PM
  • That's the problem, because we're reflecting upon a COM object that's an interface, and in a hierarchy, reflection doesn't seem to yield the data types. Perhaps I'm missing some BindingFlag that will reveal the properties of the right interface (ContactItem, _ContactItem, ContactItemClass, other?). I've tried various approaches but just haven't been able to get a type off of any reflected properties. If anyone here could provide code which returns just a single property and datatype, I'd appreciate it. Specifically Contact.Birthday. With that example I'll be able to loop through all the rest of them. I could be missing something simple.

    Thanks.

    Monday, July 16, 2012 11:26 PM
  • Sorry, and to further answer your question. The code that's generating the code here doesn't know all of the properties in the Outlook item. That's where reflection comes in - to iterate through the property list and get the property names so that I can then get the types and generate my code for each property.
    Monday, July 16, 2012 11:33 PM
  • Try to cast to the particular interface first (IContactItem), not just a generic "object".


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.3 is now available!

    Monday, July 16, 2012 11:34 PM