Other Posts in Exchange

  1. Getting Free/Busy Data from an Exchange Server
  2. Getting a Users Contacts List from an Exchange Server
  3. Getting the GAL from Exchange in C#
  4. Using WebDAV to Get Calendar Items (Appointments) from Exchange in C#/ASP.Net

Getting Free/Busy Data from an Exchange Server

3/21/2008

Ever wanted to know when someone was busy so you could plan a meeting? In outlook you'll notice a nice graph that shows that information when creating a meeting. How can we get that same information on our website? This is actually pretty easy to do and uses OWA to accomplish it. All we need to do is query the Exchange server, get an XML doc that contains that information, parse said XML doc, and voila we have our info. Without further ado, here's the code:

   1: /// <summary>
   2: /// Checks if a person/group of people are free for a specified time
   3: /// </summary>
   4: /// <param name="People">The people to check on</param>
   5: /// <param name="StartTime">The start time</param>
   6: /// <param name="EndTime">The end time</param>
   7: /// <param name="Interval">The interval in minutes at which to check (the minimum is 10 minutes)</param>
   8: /// <param name="UserName">The username of the person checking</param>
   9: /// <param name="Password">The password of the person checking</param>
  10: /// <param name="TimeZoneDifference">Time zone difference</param>
  11: /// <param name="Server">Server name</param>
  12: /// <returns>returns an array of bytes stating whether someone is free or not, a 1 means they are not free during that time and a 0 means they are free</returns>
  13: public static byte[] GetFreeBusyData(StringDictionary People, DateTime StartTime, DateTime EndTime, int Interval,
  14:     string UserName, string Password, string Server, string TimeZoneDifference)
  15: {
  16:     if (People.Count < 1)
  17:         return null;
  18:     if (StartTime >= EndTime)
  19:         return null;
  20:     string EmailAddresses = "";
  21:     foreach (string Person in People.Values)
  22:     {
  23:         EmailAddresses += "&u=SMTP:" + Person;
  24:     }
  25:     string Url = Server + "/public/?cmd=freebusy&start=" + StartTime.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss") + TimeZoneDifference + "&end=" + EndTime.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss") + TimeZoneDifference + "&interval=" + Interval.ToString() + EmailAddresses;
  26:  
  27:     System.Net.CredentialCache MyCredentialCache = new System.Net.CredentialCache();
  28:     if (!string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(Password))
  29:     {
  30:         MyCredentialCache.Add(new System.Uri(Url),
  31:                             "NTLM",
  32:                             new System.Net.NetworkCredential(UserName, Password, "")
  33:                             );
  34:     }
  35:     else
  36:     {
  37:         MyCredentialCache.Add(new System.Uri(Url),
  38:                                "Negotiate",
  39:                                (System.Net.NetworkCredential)CredentialCache.DefaultCredentials);
  40:     }
  41:  
  42:     System.Net.HttpWebRequest Request = (System.Net.HttpWebRequest)HttpWebRequest.Create(Url);
  43:     Request.Credentials = MyCredentialCache;
  44:     Request.Method = "GET";
  45:     Request.ContentType = "text/xml; encoding='utf-8'";
  46:     Request.UserAgent = "Mozilla/4.0(compatible;MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1)";
  47:     Request.KeepAlive = true;
  48:     Request.AllowAutoRedirect = false;
  49:  
  50:     System.Net.WebResponse Response = (HttpWebResponse)Request.GetResponse();
  51:     byte[] bytes = null;
  52:     using (System.IO.Stream ResponseStream = Response.GetResponseStream())
  53:     {
  54:         XmlDocument ResponseXmlDoc = new XmlDocument();
  55:         ResponseXmlDoc.Load(ResponseStream);
  56:         XmlNodeList DisplayNameNodes = ResponseXmlDoc.GetElementsByTagName("a:item");
  57:         if (DisplayNameNodes.Count > 0)
  58:         {
  59:             for (int i = 0; i < DisplayNameNodes.Count; i++)
  60:             {
  61:                 XmlNodeList Nodes = DisplayNameNodes[i].ChildNodes;
  62:                 foreach (XmlNode Node in Nodes)
  63:                 {
  64:                     if (Node.Name == "a:fbdata")
  65:                     {
  66:                         bytes = new byte[Node.InnerText.Length];
  67:                         for (int x = 0; x < Node.InnerText.Length; ++x)
  68:                         {
  69:                             bytes[x] = byte.Parse(Node.InnerText[x].ToString());
  70:                         }
  71:                     }
  72:                 }
  73:             }
  74:         }
  75:         else
  76:         {
  77:             throw new Exception("Could not get free/busy data from the exchange server");
  78:         }
  79:         // Clean up.
  80:         ResponseStream.Close();
  81:         Response.Close();
  82:     }
  83:     return bytes;
  84: }

And that's all there is to it. This function will query the Exchange server and return a byte array containing the information. A 0 means not busy, 2 means it doesn't know, and anything else pretty much means busy. Also note that the array is divided into minutes based on the interval you give. So if the start and end time are an hour away and you put it at 10 minute intervals, you'll get an array with the size of 6. Another thing to note is that this comes from my utility library and if you run into a bug, I would check there if there has been an update to the code. Anyway, try out the code, leave feedback, and happy coding.



Comments