Tuesday, December 20, 2005

So if you're working with Microsoft's new Microsoft.WindowsMobile.PocketOutlook namespace and trying to use the OutlookCollection.Restrict method to filter by a Contact's (or any PimItem's) ItemId field, you will likely run into a problem.

First, let me say the ItemID Class sucks.  It exposes basically nothing useful but a ToString() method, even though it holds numeric data.  And the first item added to POOM gets the ItemId of 0x80000001, which you might note is an *unsigned* number (again, the CLS is a pain for not allowing unsigned numbers).  So if you have an ItemId class and you want to use it, you have to do something like this:

unchecked
{
    int myId = int
.Parse(m_outlookSession.Contacts.Items[0].ItemId.ToString())
}

Really, that's how you have to do it.

So, let's say we have a Contact's ItemId and we want to see if the current session has said Contact.  One might try this:

m_outlookSession.Contacts.Items.Restrict("[ItemId]=" + itemId.ToString());

A nice try, but that gives you the not-so-helpful exception:

The query string is incorrectly formatted.
Parameter name: [ItemId]=-2147483647

Alright, so ItemId only exposes itself as a string, and Restrict has little in the way of useful documentation or samples, so maybe we can try it as a string like so:

m_outlookSession.Contacts.Items.Restrict("[ItemId]='" + itemId.ToString() + “'“);

Well that gives a similar exception, just adding the single quotes:

The query string is incorrectly formatted.
Parameter name: [ItemId]=-'2147483647'

Because I've used POOM from C++, I know that ItemId seems new to me, so just as a lark I figure I'll try 'Oid' as a field name instead, and keep it as a numeric:

m_outlookSession.Contacts.Items.Restrict("[Oid]=" + itemId.ToString());

Lo and behold, success!

Now technically this might not be a true bug, but it's sure not documented anywhere, nor would it be at all intuitive to guess if you'd not used C++ to access an IContact (which exports an Oid field, *not* an ItemId) before.  Bad Windows Mobile Team.  BAD!

Things needed:

  • The ItemID needs to have an explicit operator for conversion to an int at the very least.  A ToInt32 or ToIntPtr or something of the sort would be useful.
  • Either name the field Oid like it's stored in the database, or provide some sort of substitution so when I filter by ItemId the underlying class converts that to Oid.
  • The least they could have done was give exception text like “The field cannot be found in the collection“
  • Documenting how to remove a Restrict once set would be useful (I used Restrict(“[Oid]<>0“) for lack of any better idea)
12/20/2005 10:15:43 PM (Eastern Standard Time, UTC-05:00)  #    Comments [4]  | 
12/21/2005 5:56:37 PM (Eastern Standard Time, UTC-05:00)
Thanks...this is exactly what i was looking for. CF2 seems so much better than CF1 in many regards, then they just blew it on some things. ItemID isn't in the ContactProperty thing either...
patrick
12/27/2005 7:37:09 PM (Eastern Standard Time, UTC-05:00)
The ItemID is not always a representation of the OID, in the case of Messages, it represents the EntryID.

If you want to get a contact from an OID you can just use the Contact constructor that takes the ItemId. Something like

Contact myContact = new Contact(id);

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/mobilesdk5/html/C_Microsoft_WindowsMobile_PocketOutlook_Contact_ctor_1_b7dcdae4.asp

12/28/2005 10:47:55 AM (Eastern Standard Time, UTC-05:00)
And that's poor architecture. If ItemID can be a few different things, then the architects should have used polymorphism - after all that's exatly what it's for. ItemID should be a base class and then OID for Contacts and EntryID for Messages should derive from it. The I could determine the actual type at runtime and get methods like ToInt() for an OID.

Thanks for the pointer on using the ctor as a filter.
10/12/2006 12:55:58 AM (Eastern Daylight Time, UTC-04:00)
And to think I just spent the past 2 hrs bashing my head against the desk wondering why OutlookSession.Contacts.Items.Find wasn't working with ItemId...

Any idea on when they're going to fix it?

.NET cf SP2 perhaps?
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):