Getting a Users Contacts List from an Exchange Server

A request that recently popped up at work was the ability to use a person's contacts list from outlook when they were using a particular portion of the intranet site. Not that difficult to do actually. All that is required is a call using WebDAV to the exchange server and we have that user's contact's list. Actually there are a couple of ways to accomplish it but I found that to be the easiest. Anyway, as always I'm sure you're interested in the code:

public static System.Web.UI.WebControls.ListItemCollection GetContacts(string UserName,string Password,string Directory)

{
    System.Web.UI.WebControls.ListItemCollection ReturnArray = new System.Web.UI.WebControls.ListItemCollection();
    string server = "http:/ /ExchangeServer";
    NetworkCredential credentials = new NetworkCredential(UserName, Password);
    string uri = string.Format("{0}/exchange/{1}", server, credentials.UserName);
    byte[] contents = System.Text.Encoding.UTF8.GetBytes(string.Format(

       @"<?xml version=""1.0""?>

        <g:searchrequest xmlns:g=""DAV:"">

            <g:sql>

                SELECT

                    ""urn:schemas:contacts:givenName"", ""urn:schemas:contacts:sn"",

                    ""urn:schemas:contacts:email1""

                FROM

                    Scope('SHALLOW TRAVERSAL OF ""{0}/exchange/{1}/contacts""')

            </g:sql>

        </g:searchrequest>",

      server, credentials.UserName));

 

    HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
    request.Credentials = credentials;
    request.Method = "SEARCH";
    request.ContentLength = contents.Length;
    request.ContentType = "text/xml";

    using (System.IO.Stream requestStream = request.GetRequestStream())
        requestStream.Write(contents, 0, contents.Length);

 

    using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
    using (System.IO.Stream responseStream = response.GetResponseStream())
    {
        XmlDocument document = new XmlDocument();
        document.Load(responseStream);
        foreach (XmlElement element in document.GetElementsByTagName("a:prop"))
        {
            if (element["d:sn"] != null && element["d:givenName"] != null && element["d:email1"] != null)
            {
                System.Web.UI.WebControls.ListItem TempItem = new System.Web.UI.WebControls.ListItem();
                TempItem.Text = element["d:sn"].InnerText+", "+element["d:givenName"].InnerText;
                TempItem.Value = element["d:email1"].InnerText;
                ReturnArray.Add(TempItem);
            }
        }
    }
    return ReturnArray;
}

Note that this code is a modified version of the code you'll find here. All this call does, is makes a call doing WebDAV asking the exchange server to search the person's contacts directory and return an item's first name, last name, and email address. We can get a lot more information if needed, you can look at the urn:schemas:contacts namespace if you want something else. Once we have the information, it just creates a ListItemCollection and drops the items in there (I was using this in a drop down list). You can of course create your own Contacts class and put the info in there if you prefer. Anyway, use the code, leave feedback, and happy coding.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 4/24/2008 at 11:31 AM
Tags: , ,
Categories: ASP.Net | Web Design
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Getting Free/Busy Data from an Exchange Server

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 voilà we have our info. Without further ado, here's the code:

        public static byte[] GetFreeBusy(string People, DateTime StartTime, DateTime EndTime, int Interval, string UserName, string Password)
        {
            string EmailAddresses = "&u=SMTP:" + People;

            //Make sure to switch this to point to your exchange server
            string Url = "exchangeserver/public/?cmd=freebusy&start=" + StartTime.Date.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss") + "-05:00&end=" + EndTime.AddDays(1).Date.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss") + "-05:00&interval=" + Interval.ToString() + EmailAddresses;

            System.Net.HttpWebRequest Request;
            System.Net.WebResponse Response;
            System.Net.CredentialCache MyCredentialCache;

            byte[] bytes = null;
            System.IO.Stream ResponseStream = null;
            XmlDocument ResponseXmlDoc = null;
            XmlNodeList DisplayNameNodes = null;

            try
            {
                MyCredentialCache = new System.Net.CredentialCache();
                MyCredentialCache.Add(new System.Uri(Url),
                   "NTLM",
                   new System.Net.NetworkCredential(UserName, Password, "")
                   );

                Request = (System.Net.HttpWebRequest)HttpWebRequest.Create(Url);

                Request.Credentials = MyCredentialCache;

                Request.Method = "GET";
                Request.ContentType = "text/xml; encoding='utf-8'";
                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)";
                Request.KeepAlive = true;
                Request.AllowAutoRedirect = false;

                Response = (HttpWebResponse)Request.GetResponse();
                ResponseStream = Response.GetResponseStream();

                ResponseXmlDoc = new XmlDocument();
                ResponseXmlDoc.Load(ResponseStream);

                DisplayNameNodes = ResponseXmlDoc.GetElementsByTagName("a:item");

                if (DisplayNameNodes.Count > 0)
                {
                    for (int i = 0; i < DisplayNameNodes.Count; i++)
                    {
                        XmlNodeList Nodes = DisplayNameNodes[i].ChildNodes;
                        foreach (XmlNode Node in Nodes)
                        {
                            if (Node.Name == "a:fbdata")
                            {
                                bytes = new byte[Node.InnerText.Length];
                                for (int x = 0; x < Node.InnerText.Length; ++x)
                                {
                                    bytes[x] = byte.Parse(Node.InnerText[x].ToString());
                                }
                            }
                        }
                    }
                }
                else
                {
                    throw new Exception("Could not get free/busy data from the exchange server");
                }
                ResponseStream.Close();
                Response.Close();
                return bytes;

            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

 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. Anyway, test out the code, leave feedback, etc.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 3/21/2008 at 11:47 AM
Tags: ,
Categories: ASP.Net | C# | Web Design
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Getting a User's Email Address from an Exchange Server

Let's say that you have a user's name and you want to send a bit of mail to them using an ASP.Net page. At the same time you have an Exchange server. By using the following function you can easily get that information:

public static string GetUsersEmail(string User, string UserName, string Password)
{
   string EmailAddress = "";
   DirectoryEntry Entry = new DirectoryEntry("LDAP://exchangeserver",   //Make sure to point this at your exchange server
                                               UserName,
                                               Password,
                                               AuthenticationTypes.Secure);
   DirectorySearcher Searcher = new DirectorySearcher(Entry);
   Searcher.PropertiesToLoad.Add("mail");
   string Filter = String.Format("(&(objectcategory=user)(cn=" + User + "))");

   Searcher.Filter = Filter;
   Searcher.Sort.Direction = SortDirection.Ascending;
   Searcher.Sort.PropertyName = "cn";

   SearchResultCollection Results;

   Results = Searcher.FindAll();

   foreach (SearchResult Result in Results)
   {
      ResultPropertyCollection Properties = Result.Properties;
      foreach (string Key in Properties.PropertyNames)
      {
         if (Key == "mail")
         {
            foreach (object Values in Properties[Key])
            {
               EmailAddress = Values.ToString();
            }
         }
      }
   }
   return EmailAddress;
}

All this function is doing is using LDAP to query the server for a user's information and specifically their email address. This function can come in handy more often than you think. You might get the name of a user from the GAL, from getting a list of members of a group, etc. Or you may simply be given the name by the user. In any case I've found that this comes in handy and I'll even show you in some future posts how to put this to good use. Anyway, feel free to use the code, leave comments, etc.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 3/14/2008 at 1:35 PM
Tags: ,
Categories: C# | Web Design
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed