InfiniTec - Henning Krauses Blog

Don't adjust your mind - it's reality that is malfunctioning

Constructing OWA 2007 item ids from WebDAV items

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:

  1. Load the entry id via WebDAV (PROPFIND or SEARCH on the item, get property http://schemas.microsoft.com/mapi/proptag/xfff0102).
  2. Decode the BASE64 encoded entry id to a byte array (in .NET, use the Convert.FromBase64String() method)
  3. Create a new byte array with the length of the entryid byte array plus 2
  4. Write the length of the entry id in the first byte of the byte array
  5. Copy the entry id to the new byte array, starting at offset 1
  6. Write the item type identifier into the last byte of the element
  7. Convert the byte array to a BAS64 encoded string (using Convert.ToBase64String() method)
  8. 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 }

 


Technorati:

Posted by Henning Krause on Saturday, March 24, 2007 12:00 AM, last modified on Sunday, November 28, 2010 9:56 PM
Permalink | Post RSSRSS comment feed

Comments (3) -

On 6/3/2008 11:27:29 AM R. Frese Germany wrote:

R. Frese

Hello,
and for items in public folders - available since SP1 for Exchange 2007 - the url is again different, e.g.:

'/owa/default.aspx?ae=Item&a=Open&t=IPM.note&id=PSI.LgAAAAAaRHOQqmYRzZvIAKoAL8RaAwCzfAxt%2fGC2SYdQnhZMvzCDAdVHEaWEAAAB.RgAAAAAaRHOQqmYRzZvIAKoAL8RaCQCzfAxt%2fGC2SYdQnhZMvzCDAdVHEaWEAACzfAxt%2fGC2SYdQnhZMvzCDAdVHEeJ%2bAAAA'

where :
id=PSI.LgAAAAAaRHOQqmYRzZvIAKoAL8RaAwCzfAxt%2fGC2SYdQnhZMvzCDAdVHEaWEAAAB.RgAAAAAaRHOQqmYRzZvIAKoAL8RaCQCzfAxt%2fGC2SYdQnhZMvzCDAdVHEaWEAACzfAxt%2fGC2SYdQnhZMvzCDAdVHEeJ%2bAAAA

is the interisting part of the url.
For that url the function "CreateOwaUrl(string entryId, ItemType itemTypeId)" *fails*, cause the pub.fold url contains "." (points), which aren't allowed characters for base64 encoding.
Exchange 2007 SP1 introduced the new functions to converting url from OWA to PR_ENTRYID as described in msdn.microsoft.com/.../bb856559(EXCHG.80).aspx, but that doesn't work for public folders.
And the format of public folder urls are not described nowhere.

So, how is it possibel to get the properties of an item in a specific public folder via Exchange Web Service?
Any idea?

regards
R. Frese

On 6/26/2008 4:05:11 PM jpf Belgium wrote:

jpf

Hi,

I currently use this kind of following url to link to "public folders" :

http(s)://<exchangeserver>/owa/?ae=Folder&id=PSF." + <array-size = EntryId.length/2> + < Escape Hexa Base64 encoded entryid> + <something related to the folder (x13)>

Note: the type parameter is not mandatory (&t=IPN.Note) but it is easy to know it with the MAPIfolder.DefaultMessageClass property

if you got a entryid of 92 caracteres 00001A...., fill the array like this :
  owaId[0] = x2E (92/2 = 46)
  owaId[1] = x00
  owaId[2] = x00
  owaId[3] = x1A
     ...

don't forget to use System.Uri.EscapeDataString() or something else 'coz "+" caractere should be replace with %2B etc.

On 8/14/2009 2:59:55 AM ZippyRainbow Australia wrote:

ZippyRainbow

Hi,

I think I have basically got this sorted.. but I must be missing one step, as my ID is a little bit different to what the link is if I click on the Email under OWA Exchange 2007 SP1.

My Result should be : (As Copied from when I double click on the email in OWA)
https://sites/owa/?ae=Item&a=Open&t=IPM.Note&id=RgAAAADTZ%2fBDv0aiQLUOdKWZH5IqBwC%2bzheUSRzNRbQgVSZ558klAAqCGlP5AAC%2bzheUSRzNRbQgVSZ558klAAqorqGiAAAJ

But I Get :     (From my VB.net Project)
https://sites/owa/?ae=Item&a=Open&t=IPM.Note&id=RgAAAADTZ%2fBDv0aiQLUOdKWZH5IqBwC%2bzheUSRzNRbQgVSZ558klAAqorWEfAAC%2bzheUSRzNRbQgVSZ558klAAqorqGiAAAJ

Note the Difference is in the Middle.. I am getting qorWEfAAC% and not qCGlP5AAC%

This is my Conversion Code for the EntryID... Converted into VB.net

Private Function CreateOwaUrl(ByVal entryId As String) As String
        '1.Load the entry id via WebDAV (PROPFIND or SEARCH on the item, get property http://schemas.microsoft.com/mapi/proptag/xfff0102).
        
        Dim itemTypeId As Byte = 9      'Normally a Message for me.
        Dim binaryEntryId() As Byte        
        Dim result As String
        
        '2.Decode the BASE64 encoded entry id to a byte array (in .NET, use the Convert.FromBase64String() method)
        binaryEntryId = Convert.FromBase64String(entryId)

        '3.Create a new byte array with the length of the entryid byte array plus 2        
        Dim owaId As Byte() = New Byte(binaryEntryId.Length + 1) {}

        '4.Write the length of the entry id in the first byte of the byte array
        owaId(0) = CType(binaryEntryId.Length, Byte)

        '5.Copy the entry id to the new byte array, starting at offset 1
        Array.Copy(binaryEntryId, 0, owaId, 1, binaryEntryId.Length)

        '6.Write the item type identifier into the last byte of the element ... Normally 9 for a Message
        owaId((owaId.Length - 1)) = CType(itemTypeId, Byte)

        '7.Convert the byte array to a BAS64 encoded string (using Convert.ToBase64String() method)
        result = Convert.ToBase64String(owaId)

        '8.Urlencode the string
        result = System.Web.HttpUtility.UrlEncode(result)
        Return result
    End Function

 +Pingbacks and trackbacks (1)