DAV: How To Search Calendar For Conflicts

Here is a WebDAV sample for searching a user’s calendar for conflicts. Given a mailbox name and timeframe it will search for any appointments…

//************************************

// Get the contents of the calendar within a date range

// CREATED BY: mstehle

// CREATED ON: 6/9/06

//************************************

public string SearchCalendar(string mailboxName, DateTime start,

    DateTime end)

{

    // Build the Calendar folder URL

    string calFolderUrl = string.Format("https://{0}/exchange/{1}/calendar/",

        _server, mailboxName);

      // Build the SQL query.

      string strQuery;

  strQuery = "<?xml version=\"1.0\"?>" +

                "<D:searchrequest xmlns:D = \"DAV:\">" +

                "<D:sql>" +

                "SELECT \"DAV:displayname\" " +

                "FROM scope('shallow traversal of \"" + calFolderUrl + "\"') " +

                "WHERE \"DAV:isfolder\" = false " +

                "AND (\"urn:schemas:calendar:dtstart\" &lt;= CAST(\""

                    + Utils.ConvertToISO8601(end) + "\" as 'dateTime')) " +

                "AND (\"urn:schemas:calendar:dtend\" &gt;= CAST(\""

                    + Utils.ConvertToISO8601(start) + "\" as 'dateTime')) " +

                "</D:sql>" +

                "</D:searchrequest>";

    // DEBUG: Print out the SEARCH Query

    Debug.WriteLine(strQuery);

      // Create the HttpWebRequest object.

    System.Net.HttpWebRequest request =

        (System.Net.HttpWebRequest)HttpWebRequest.Create(calFolderUrl);

      // Create credentials from user name and password

      System.Net.CredentialCache creds = new CredentialCache();

    System.Uri folderUri = new Uri(calFolderUrl);

    System.Net.NetworkCredential netCred =

        new NetworkCredential(_userName, _password, _domain);

      creds.Add(folderUri, "Basic", netCred);

      request.Credentials = creds.GetCredential(folderUri, "Basic");

      // Specify the method.

      request.Method = "SEARCH";

      request.ContentType = "text/xml";

    request.Headers.Add("translate", "f");

      request.KeepAlive = true;

      request.AllowAutoRedirect = false;

      // Encode the body using UTF-8.

      byte[] bytes = null;

      bytes = Encoding.UTF8.GetBytes((string)strQuery);

      // Set the content header length. This must be

      // done before writing data to the request stream.

      request.ContentLength = bytes.Length;

      System.IO.Stream requestStream = request.GetRequestStream();

      requestStream.Write(bytes, 0, bytes.Length);

      requestStream.Close();

      // Send the SEARCH method request and get the

      // response from the server.

      System.Net.WebResponse response = (HttpWebResponse)request.GetResponse();

      System.IO.Stream responseStream = response.GetResponseStream();

    System.IO.StreamReader responseReader =

        new System.IO.StreamReader(responseStream);

    string strResponse = responseReader.ReadToEnd();

      // Clean up.

    responseReader.Close();

      responseStream.Close();

      response.Close();

    // DEBUG: Print out the response string

    Debug.WriteLine(strResponse);

    return strResponse;

}

In order to properly check for appointments within a given timeframe, we need to look for any appointment that begins before the end datetime and ends after the start datetime.

For example, if we are searching within a single day for a block of time between 2:00 PM and 3:00 PM for existing appointments. The following appointments fall within that timeframe 10:00 AM - 4:00 PM, 2:15 PM - 2:45 PM, and 2:55 PM - 3:30 PM. Therefore we can't simply search for appointments whose start times are greater than the start times and end times are less than the end times.

…Like many I missed this logic the first time I tried to right this function. This is a very useful query to use when checking real time availability of user…