Prior Exchange 2007, it was easy for an application to get an url for any Exchange item which could be used to open the element in a browser: Simply use the DAV:href property which could be retrieved from any item.
When you try this with Exchange 2007, you won't get the expected result. Outlook Web Access 2007 (OWA) uses a different schema to open files. Instead of
1 http://server/exchange/alias/contacts/test.eml
OWA 2007 uses this format:
1 https://server/owa/?ae=Item&a=Open&t=IPM.Contact&s=Draft&id=RgAAAADns5U5Pdo%2bSamzP%2fK78yQOBwBgW74qsZ7RTJzeGdXyv4QaAAhgHichAABgW74qsZ7RTJzeGdXyv4QaAAhgHjBxAAAR
But if you query the DAV:href property via WebDAV in Exchange 2007, you still get the url as seen in the first example. The tricky part of the second url is clearly the id parameter, as everything else is either static (depending on the operation one wants to perform) or can be directly derived from the item (the message class for example).
It turns out that the id parameter is a modified version of the entry id of the element. To derive the id from the entry id, you must follow these steps:
- Load the entry id via WebDAV (PROPFIND or SEARCH on the item, get property http://schemas.microsoft.com/mapi/proptag/xfff0102).
- Decode the BASE64 encoded entry id to a byte array (in .NET, use the Convert.FromBase64String() method)
- Create a new byte array with the length of the entryid byte array plus 2
- Write the length of the entry id in the first byte of the byte array
- Copy the entry id to the new byte array, starting at offset 1
- Write the item type identifier into the last byte of the element
- Convert the byte array to a BAS64 encoded string (using Convert.ToBase64String() method)
- Urlencode the string
Here is a C# snippet which does the conversion:
1 publicstaticstring CreateOwaUrl(string entryId, ItemType itemTypeId)
2 {
3 byte[] binaryEntryId;
4 byte[] owaId;
5 string result;
6
7 binaryEntryId = Convert.FromBase64String(entryId);
8 owaId = newbyte[binaryEntryId.Length+2];
9 owaId[0] = (byte) binaryEntryId.Length;
10 Array.Copy(binaryEntryId, 0, owaId, 1, binaryEntryId.Length);
11 owaId[owaId.Length - 1] = (byte) itemTypeId;
12
13 result = Convert.ToBase64String(owaId);
14 result = System.Web.HttpUtility.UrlEncode(result);
15
16 return result;
17 }
I've discovered most of the item identifiers, but there are certainly more...
1 publicenumItemType: byte
2 {
3 None = 0,
4 Folder = 0x1,
5 CalendarFolder = 0x2,
6 ContactsFolder = 0x3,
7 TasksFolder = 0x4,
8 NotesFolder = 0x5,
9 JournalFolder = 0x6,
10 Message = 0x9,
11 MeetingMessage = 0xa,
12 CalendarItem = 0xf,
13 CalendarItemOccurrence = 0x10,
14 Contact = 0x11,
15 DistributionList = 0x12,
16 Task = 0x13,
17 TaskRequest = 0x14,
18 Note = 0x15,
19 Post = 0x16,
20 }