This url never changes unless the item is moved to another folder.
Below is method which constructs such a permanent url based on the url to the store (the http://server/exchange/user in the above example) and an EntryId structure:
1 using System;
2 using System.Globalization;
3 using System.IO;
4
5 namespace InfiniTec.Exchange
6 {
7 staticclassExchangeStoreReference
8 {
9 publicstaticstring DecodeEntryId(BinaryReader reader, string baseUrl)
10 {
11 Guid folderId;
12 ulong folderCnt;
13
14 // First reserved field
15 reader.ReadUInt32();
16
17 // Now comes the store guid.
18 reader.ReadBytes(16);
19
20 // Next reserved field
21 reader.ReadUInt16();
22
23 folderId = ReadGuid(reader);
24 folderCnt = SwapUInt64(reader.ReadUInt64());
25
26 if (!baseUrl.EndsWith("/"))
27 {
28 baseUrl += "/";
29 }
30
31 if (reader.BaseStream.Length - reader.BaseStream.Position >= 24)
32 {
33 Guid messageId;
34 messageId = ReadGuid(reader);
35 ulong messageCnt;
36 messageCnt = SwapUInt64(reader.ReadUInt64());
37 baseUrl += string.Format(CultureInfo.CurrentCulture, baseUrl + "/-FlatUrlSpace-/{0:N}-{1:x}/{2:N}-{3:x}", folderId, folderCnt, messageId, messageCnt);
38 }
39 else
40 {
41 baseUrl += string.Format(CultureInfo.CurrentCulture, baseUrl + "/-FlatUrlSpace-/{0:N}-{1:x}", folderId, folderCnt);
42 }
43 return baseUrl;
44
45 }
46
47 privatestaticGuid ReadGuid(BinaryReader reader)
48 {
49 int a;
50 short b, c;
51
52 a = SwapInt(reader.ReadUInt32());
53 b = reader.ReadInt16();
54 c = SwapShort(reader.ReadUInt16());
55 returnnewGuid(a, b, c, reader.ReadBytes(8));
56 }
57
58 privatestaticshort SwapShort(ushort value)
59 {
60 unchecked
61 {
62 ushort result;
63 result = (ushort)(((value & 0xFF00) >> 8) |
64 ((value & 0x00FF) << 8));
65
66 return (short)result;
67 }
68 }
69
70 privatestaticint SwapInt(uint value)
71 {
72 uint result;
73
74 result = ((value & 0xFF000000) >> 24) |
75 ((value & 0x00FF0000) >> 8) |
76 ((value & 0x0000FF00) << 8) |
77 ((value & 0x000000FF) << 24);
78
79 unchecked
80 {
81 return (int)result;
82 }
83 }
84
85
86 privatestaticulong SwapUInt64(ulong value)
87 {
88 uint lo;
89 uint hi;
90 ulong result;
91
92 lo = (uint)(value & 0xffffffff);
93 hi = ((uint)(value >> 32)) & 0xffffffff;
94
95 lo = ((lo & 0xFF000000) >> 8) |
96 ((lo & 0x00FF0000) << 8) |
97 ((lo & 0x0000FF00) >> 8) |
98 ((lo & 0x000000FF) << 8);
99
100 hi = ((hi & 0xFF000000) >> 8) |
101 ((hi & 0x00FF0000) << 8) |
102 ((hi & 0x0000FF00) >> 8) |
103 ((hi & 0x000000FF) << 8);
104
105 result = (((ulong)lo) << 32) | hi;
106
107 return result;
108 }
109 }
110 }
As you can see, there is some bit-flipping going on during the process. This is because the guids in the EntryId are stored differently than they are used in the permanent url. At last, the folder id, folder sequence number, element id and element sequence number are concatenated and appended to the base url. The result is a permanent url which can be used to access the element.
To use this method, just wrap the binary value of the EntryId in a BinaryReader class and pass that instance to the DecodeEntryId method.