Searching Calendar Folders with WebDAV

Searching Calendar Folders with WebDAV

This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.

This topic shows the WebDAV SEARCH query to search for calendar folders. See Searching Folders (WebDAV) for how to construct the query and to enumerate its results.

See Constructing Exchange Store HTTP URLs and Authentication and Security Using WebDAV for more information.

This topic contains Microsoft® Visual Basic® Scripting Edition (VBScript), Microsoft C#, and Visual Basic .NET code examples.

SEARCH /exchange/~username/calendar/ HTTP/1.1
Host: www.fourthcoffee.com
Content-Type: text/xml

<?xml version="1.0"?>
<g:searchrequest xmlns:g="DAV:">
        <g:sql> Select "urn:schemas:calendar:location", "urn:schemas:httpmail:subject",
                "urn:schemas:calendar:dtstart", "urn:schemas:calendar:dtend",
                "urn:schemas:calendar:busystatus", "urn:schemas:calendar:instancetype"
                FROM Scope('SHALLOW TRAVERSAL OF "/exchange/~username/calendar/"')
                WHERE NOT "urn:schemas:calendar:instancetype" = 1
                AND "DAV:contentclass" = 'urn:content-classes:appointment'
                AND "urn:schemas:calendar:dtstart" > '2003/06/01 00:00:00'
                ORDER BY "urn:schemas:calendar:dtstart" ASC
         </g:sql>
</g:searchrequest>

VBScript

The following example uses the SEARCH Method to search a calendar folder for calendar items with a start time after 01 June 2003 and display the location Field, subject Field, dtstart Field, dtend Field, busystatus Field, and instancetype Field for each returned calendar item.

Option Explicit

' Variables.
Dim strCalendarURI           ' As String
Dim reqDoc                   ' As Msxml2.DOMDocument
Dim resDoc                   ' As Msxml2.DOMDocument
Dim pi                       ' As IXMLDOMProcessingInstruction
Dim strPassword              ' As String
Dim strUserName              ' As String
Dim searchrequestNode        ' As IXMLDOMNode
Dim sqlNode                  ' As IXMLDOMNode
Dim strQuery                 ' As String
Dim queryNode                ' As IXMLDOMText
Dim req                      ' As MSXML2.XMLHTTP
Dim objSubjectNodeList       ' As IXMLDOMNodeList
Dim objLocationNodeList      ' As IXMLDOMNodeList
Dim objStartTimeNodeList     ' As IXMLDOMNodeList
Dim objEndTimeNodeList       ' As IXMLDOMNodeList
Dim objBusyStatusNodeList    ' As IXMLDOMNodeList
Dim objInstanceTypeNodeList  ' As IXMLDOMNodeList
Dim objNode                  ' As IXMLDOMNode
Dim i                        ' As Integer
Dim strInstanceType          ' As String

' Initialize variables.
strUserName = "Domain\UserName"
strPassword = "!Password"
strCalendarURI = "https://server/exchange/username/calendar/"
set reqDoc = createobject("microsoft.xmldom")
set resDoc = createobject("microsoft.xmldom")
set pi = reqDoc.createProcessingInstruction("xml","version=""1.0""")

' Append processing instruction node to the DOM document.
reqDoc.appendChild pi

' Create the DAV:searchrequest node and set it
' to the root element of the document.
set searchrequestNode = reqDoc.createNode(1,"searchrequest","DAV:")
set reqDoc.documentElement = searchrequestNode

' Create the DAV:sql node and append it to the root element.
set sqlNode = reqDoc.createNode(1,"sql","DAV:")
searchrequestNode.appendChild sqlNode

' Build the SQL query.
strQuery = "SELECT ""urn:schemas:calendar:location"", ""urn:schemas:httpmail:subject"", "
strQuery = strQuery & " ""urn:schemas:calendar:dtstart"", ""urn:schemas:calendar:dtend"", "
strQuery = strQuery & " ""urn:schemas:calendar:busystatus"", ""urn:schemas:calendar:instancetype"" "
strQuery = strQuery & " FROM Scope('SHALLOW TRAVERSAL OF """ & strCalendarURI & """') "
strQuery = strQuery & "WHERE NOT ""urn:schemas:calendar:instancetype"" = 1 "
strQuery = strQuery & "AND ""DAV:contentclass"" = 'urn:content-classes:appointment' "
strQuery = strQuery & "AND ""urn:schemas:calendar:dtstart"" > '2003/06/01 00:00:00' "
strQuery = strQuery & "ORDER BY ""urn:schemas:calendar:dtstart"" ASC"

' Create the SQL query textnode and append it to document.
set queryNode = reqDoc.createTextNode(strQuery)
sqlNode.appendChild queryNode

' Create the XMLHTTP object.
set req = createobject("msxml2.xmlhttp")

' Specify the SEARCH method, the URL, that the request will be sent synchronously,
' the user name, and the password.
req.open "SEARCH", strCalendarURI, false, strUserName, strPassword

' Set the Content-Type header to "text/xml".
req.setrequestheader "Content-Type", "text/xml"

' Send the SEARCH request.
req.send reqDoc

' An error occurred on the server.
If req.status >= 500 Then

   ' Display request status and status text.
   wscript.echo "Status: " & req.status
   wscript.echo "Status text: An error occurred on the server."

' Success. Display the item display names.
ElseIf req.status = 207 Then

   ' Display request status and status text.
   wscript.echo "Status: " & req.status
   wscript.echo "Status text:  " & req.statustext

   ' Get the XML response.
   set resDoc = req.responseXML

   ' Build a list of the urn:schemas:httpmail:subject XML nodes,
   ' corresponding to the calendar item subjects returned in the search request.
   ' The urn:schemas:httpmail: namespace is typically
   ' assigned the e: prefix in the XML response body.
   Set objSubjectNodeList = resDoc.getElementsByTagName("e:subject")

   ' Build a list of the urn:schemas:calendar:location XML nodes,
   ' corresponding to the calendar item locations returned in the search request.
   ' The urn:schemas:calendar: namespace is typically
   ' assigned the d: prefix in the XML response body.
   Set objLocationNodeList = resDoc.getElementsByTagName("d:location")

   ' Build a list of the urn:schemas:calendar:dtstart XML nodes,
   ' corresponding to the calendar item start times returned in the
   ' search request.
   Set objStartTimeNodeList = resDoc.getElementsByTagName("d:dtstart")

   ' Build a list of the urn:schemas:calendar:dtend XML nodes,
   ' corresponding to the calendar item end times returned in the
   ' search request.
   Set objEndTimeNodeList = resDoc.getElementsByTagName("d:dtend")

   ' Build a list of the urn:schemas:calendar:busystatus XML nodes,
   ' corresponding to the calendar item busy statuses returned in the
   ' search request.
   Set objBusyStatusNodeList = resDoc.getElementsByTagName("d:busystatus")

   ' Build a list of the urn:schemas:calendar:instancetype XML nodes,
   ' corresponding to the calendar item instance types returned in the
   ' search request.
   Set objInstancetypeNodeList = resDoc.getElementsByTagName("d:instancetype")

   If objSubjectNodeList.length > 0 Then
      wscript.echo "Calendar items..."

      ' Loop through returned calendar items.
      For i = 0 To (objSubjectNodeList.length -1)

         ' Display subject.
         Set objNode = objSubjectNodeList.nextNode
         wscript.echo "  Subject:       " & objNode.Text

         ' Display location.
         Set objNode = objLocationNodeList.nextNode
         wscript.echo "  Location:      " & objNode.Text

         ' Display start time.
         Set objNode = objStartTimeNodeList.nextNode
         wscript.echo "  Start time:    " & objNode.Text

         ' Display end time.
         Set objNode = objEndTimeNodeList.nextNode
         wscript.echo "  End time:      " & objNode.Text

         ' Display busy status.
         Set objNode = objBusyStatusNodeList.nextNode
         wscript.echo "  Busy status:   " & objNode.Text

         ' Display instance type.
         Set objNode = objInstanceTypeNodeList.nextNode
         strInstanceType = objNode.Text

         If strInstanceType = "0" Then
            wscript.echo "  Instance type: 0-Single appointment"

         ElseIf strInstanceType = "1" Then
            wscript.echo "  Instance type: 1-Master recurring appointment"

         ElseIf strInstanceType = "2" Then
            wscript.echo "  Instance type: 2-Single instance, recurring appointment"

         ElseIf strInstanceType = "3" Then
            wscript.echo "  Instance type: 3-Exception to a recurring appointment"

         Else
            wscript.echo "  Instance type: Unknown"

         End If

         wscript.echo ""
      Next
   Else
      wscript.echo "No calendar items found..."
   End If

Else
   ' Display the status, status text, and response text.
   wscript.echo "Status: " & req.status
   wscript.echo "Status text: " & req.statustext
   wscript.echo "Response text: " & req.responsetext

End If

' Clean up.
Set req = nothing

C#

The following example uses the SEARCH Method to search a calendar folder for calendar items with a start time after 01 June 2003 and display the location Field, subject Field, dtstart Field, dtend Field, busystatus Field, and instancetype Field for each returned calendar item.

using System;
using System.Net;
using System.IO;
using System.Text;
using System.Xml;

namespace ExchangeSDK.Snippets.CSharp
{
   class SearchingCalendarFoldersWebDAV
   {
      [STAThread]
      static void Main(string[] args)
      {
         // Variables.
         System.Net.HttpWebRequest Request;
         System.Net.WebResponse Response;
         System.Net.CredentialCache MyCredentialCache;
         string strCalendarURI = "https://server/exchange/username/calendar/";
         string strUserName = "UserName";
         string strPassword = "!Password";
         string strDomain = "Domain";
         string strQuery ="";
         byte[] bytes = null;
         System.IO.Stream RequestStream;
         System.IO.Stream ResponseStream;
         System.Xml.XmlDocument ResponseXmlDoc;
         System.Xml.XmlNodeList SubjectNodeList;
         System.Xml.XmlNodeList LocationNodeList;
         System.Xml.XmlNodeList StartTimeNodeList;
         System.Xml.XmlNodeList EndTimeNodeList;
         System.Xml.XmlNodeList BusyStatusNodeList;
         System.Xml.XmlNodeList InstanceTypeNodeList;

         try
         {
            // Build the SQL query.
            strQuery = "<?xml version=\"1.0\"?>"
                     + "<g:searchrequest xmlns:g=\"DAV:\">"
                     + "<g:sql>SELECT \"urn:schemas:calendar:location\", \"urn:schemas:httpmail:subject\", "
                     + "\"urn:schemas:calendar:dtstart\", \"urn:schemas:calendar:dtend\", "
                     + "\"urn:schemas:calendar:busystatus\", \"urn:schemas:calendar:instancetype\" "
                     + "FROM Scope('SHALLOW TRAVERSAL OF \"" + strCalendarURI + "\"') "
                     + "WHERE NOT \"urn:schemas:calendar:instancetype\" = 1 "
                     + "AND \"DAV:contentclass\" = 'urn:content-classes:appointment' "
                     + "AND \"urn:schemas:calendar:dtstart\" > '2003/06/01 00:00:00' "
                     + "ORDER BY \"urn:schemas:calendar:dtstart\" ASC"
                     +"</g:sql></g:searchrequest>";

            // Create a new CredentialCache object and fill it with the network
            // credentials required to access the server.
            MyCredentialCache = new System.Net.CredentialCache();
            MyCredentialCache.Add( new System.Uri(strCalendarURI),
               "NTLM",
               new System.Net.NetworkCredential(strUserName, strPassword, strDomain)
               );

            // Create the HttpWebRequest object.
            Request = (System.Net.HttpWebRequest)HttpWebRequest.Create(strCalendarURI);

            // Add the network credentials to the request.
            Request.Credentials = MyCredentialCache;

            // Specify the method.
            Request.Method = "SEARCH";

            // Encode the body using UTF-8.
            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;

            // Get a reference to the request stream.
            RequestStream = Request.GetRequestStream();

            // Write the SQL query to the request stream.
            RequestStream.Write(bytes, 0, bytes.Length);

            // Close the Stream object to release the connection
            // for further use.
            RequestStream.Close();

            // Set the content type header.
            Request.ContentType = "text/xml";

            // Send the SEARCH method request and get the
            // response from the server.
            Response = (HttpWebResponse)Request.GetResponse();

            // Get the XML response stream.
            ResponseStream = Response.GetResponseStream();

            // Create the XmlDocument object from the XML response stream.
            ResponseXmlDoc = new XmlDocument();
            ResponseXmlDoc.Load(ResponseStream);

            // Build a list of the urn:schemas:httpmail:subject XML nodes,
            // corresponding to the calendar item subjects returned in the search request.
            // The urn:schemas:httpmail: namespace is typically
            // assigned the e: prefix in the XML response body.
            SubjectNodeList = ResponseXmlDoc.GetElementsByTagName("e:subject");

            // Build a list of the urn:schemas:calendar:location XML nodes,
            // corresponding to the calendar item locations returned in the search request.
            // The urn:schemas:calendar: namespace is typically
            // assigned the d: prefix in the XML response body.
            LocationNodeList = ResponseXmlDoc.GetElementsByTagName("d:location");

            // Build a list of the urn:schemas:calendar:dtstart XML nodes,
            // corresponding to the calendar item locations returned in the search request.
            StartTimeNodeList = ResponseXmlDoc.GetElementsByTagName("d:dtstart");

            // Build a list of the urn:schemas:calendar:dtend XML nodes,
            // corresponding to the calendar item locations returned in the search request.
            EndTimeNodeList = ResponseXmlDoc.GetElementsByTagName("d:dtend");

            // Build a list of the urn:schemas:calendar:busystatus XML nodes,
            // corresponding to the calendar item locations returned in the search request.
            BusyStatusNodeList = ResponseXmlDoc.GetElementsByTagName("d:busystatus");

            // Build a list of the urn:schemas:calendar:instancetype XML nodes,
            // corresponding to the calendar item locations returned in the search request.
            InstanceTypeNodeList = ResponseXmlDoc.GetElementsByTagName("d:instancetype");

            // Loop through the returned calendar items (if any).

            if(SubjectNodeList.Count > 0)
            {
               Console.WriteLine("Calendar items...");
               for(int i=0; i<SubjectNodeList.Count; i++)
               {
                  // Display the subject.
                  Console.WriteLine("  Subject:       " + SubjectNodeList[i].InnerText);

                  // Display the location.
                  Console.WriteLine("  Location:      " + LocationNodeList[i].InnerText);

                  // Display the start time.
                  Console.WriteLine("  Start time:    " + StartTimeNodeList[i].InnerText);

                  // Display the end time.
                  Console.WriteLine("  End time:      " + EndTimeNodeList[i].InnerText);

                  // Display the busy status.
                  Console.WriteLine("  Busy status:   " + BusyStatusNodeList[i].InnerText);

                  // Display the instance type.
                  if(InstanceTypeNodeList[i].InnerText == "0")
                     Console.WriteLine("  Instance type: 0-Single appointment");
                  else if(InstanceTypeNodeList[i].InnerText == "1")
                     Console.WriteLine("  Instance type: 1-Master recurring appointment");
                  else if(InstanceTypeNodeList[i].InnerText == "2")
                     Console.WriteLine("  Instance type: 2-Single instance, recurring appointment");
                  else if(InstanceTypeNodeList[i].InnerText == "3")
                     Console.WriteLine("  Instance type: 3-Exception to a recurring appointment");
                  else
                     Console.WriteLine("  Instance type: Unknown");

                  Console.WriteLine("");
               }
            }
            else
            {
               Console.WriteLine("No calendar items found ...");
            }

            // Clean up.
            ResponseStream.Close();
            Response.Close();
         }
         catch(Exception ex)
         {
            // Catch any exceptions. Any error codes from the SEARCH
            // method request on the server will be caught here, also.
            Console.WriteLine(ex.Message);
         }
      }
   }
}

Visual Basic .NET

The following example uses the SEARCH Method to search a calendar folder for calendar items with a start time after 01 June 2003 and display the location Field, subject Field, dtstart Field, dtend Field, busystatus Field, and instancetype Field for each returned calendar item.

Option Explicit On
Option Strict On

Module Module1

Sub Main()

   ' Variables
   Dim Request As System.Net.HttpWebRequest
   Dim Response As System.Net.HttpWebResponse
   Dim MyCredentialCache As System.Net.CredentialCache
   Dim strPassword As String
   Dim strDomain As String
   Dim strUserName As String
   Dim strCalendarURI As String
   Dim strQuery As String
   Dim bytes() As Byte
   Dim RequestStream As System.IO.Stream
   Dim ResponseStream As System.IO.Stream
   Dim ResponseXmlDoc As System.Xml.XmlDocument
   Dim HrefNodes As System.Xml.XmlNodeList
   Dim SizeNodes As System.Xml.XmlNodeList
   Dim SubjectNodeList As System.Xml.XmlNodeList
   Dim LocationNodeList As System.Xml.XmlNodeList
   Dim StartTimeNodeList As System.Xml.XmlNodeList
   Dim EndTimeNodeList As System.Xml.XmlNodeList
   Dim BusyStatusNodeList As System.Xml.XmlNodeList
   Dim InstanceTypeNodeList As System.Xml.XmlNodeList

   Try
      ' Initialize variables.
      strUserName = "UserName"
      strPassword = "!Password"
      strDomain = "Domain"
      strCalendarURI = "https://server/exchange/username/calendar/"


      ' Build the SQL query.
      strQuery = "<?xml version=""1.0""?>" & _
                 "<g:searchrequest xmlns:g=""DAV:"">" & _
                 "<g:sql>SELECT ""urn:schemas:calendar:location"", ""urn:schemas:httpmail:subject"", " & _
                 """urn:schemas:calendar:dtstart"", ""urn:schemas:calendar:dtend"", " & _
                 """urn:schemas:calendar:busystatus"", ""urn:schemas:calendar:instancetype"" " & _
                 "FROM Scope('SHALLOW TRAVERSAL OF """ & strCalendarURI & """') " & _
                 "WHERE NOT ""urn:schemas:calendar:instancetype"" = 1 " & _
                 "AND ""DAV:contentclass"" = 'urn:content-classes:appointment' " & _
                 "AND ""urn:schemas:calendar:dtstart"" > '2003/06/01 00:00:00' " & _
                 "ORDER BY ""urn:schemas:calendar:dtstart"" ASC" & _
                 "</g:sql></g:searchrequest>"

      ' Create a new CredentialCache object and fill it with the network
      ' credentials required to access the server.
      MyCredentialCache = New System.Net.CredentialCache
      MyCredentialCache.Add(New System.Uri(strCalendarURI), _
          "NTLM", _
          New System.Net.NetworkCredential(strUserName, strPassword, strDomain) _
          )

      ' Create the PUT HttpWebRequest object.
       Request = CType(System.Net.WebRequest.Create(strCalendarURI), _
                       System.Net.HttpWebRequest)

      ' Add the network credentials to the request.
      Request.Credentials = MyCredentialCache

      ' Specify the SEARCH method.
      Request.Method = "SEARCH"

      ' Encode the body using UTF-8.
      bytes = System.Text.Encoding.UTF8.GetBytes(strQuery)

      ' Set the content header length.  This must be
      ' done before writing data to the request stream.
      Request.ContentLength = bytes.Length

      ' Get a reference to the request stream.
      RequestStream = Request.GetRequestStream()

      ' Write the message body to the request stream.
      RequestStream.Write(bytes, 0, bytes.Length)

      ' Close the Stream object to release the connection
      ' for further use.
      RequestStream.Close()

      ' Set the Content Type header.
      Request.ContentType = "text/xml"

      ' Set the Translate header.
      Request.Headers.Add("Translate", "F")

      ' Send the SEARCH method request and get the
      ' response from the server.
      Response = CType(Request.GetResponse(), System.Net.HttpWebResponse)

      ' Get the XML response stream.
      ResponseStream = Response.GetResponseStream()

      ' Create the XmlDocument object from the XML response stream.
      ResponseXmlDoc = New System.Xml.XmlDocument
      ResponseXmlDoc.Load(ResponseStream)

      ' Build a list of the DAV:href XML nodes, corresponding to the folders
      ' in the mailbox.  The DAV: namespace is typically assgigned the a:
      ' prefix in the XML response body.
      HrefNodes = ResponseXmlDoc.GetElementsByTagName("a:href")

      ' Build a list of the urn:schemas:httpmail:subject XML nodes,
      ' corresponding to the calendar item subjects returned in the search request.
      ' The urn:schemas:httpmail: namespace is typically
      ' assigned the e: prefix in the XML response body.
      SubjectNodeList = ResponseXmlDoc.GetElementsByTagName("e:subject")

      ' Build a list of the urn:schemas:calendar:location XML nodes,
      ' corresponding to the calendar item locations returned in the search request.
      ' The urn:schemas:calendar: namespace is typically
      ' assigned the d: prefix in the XML response body.
      LocationNodeList = ResponseXmlDoc.GetElementsByTagName("d:location")

      ' Build a list of the urn:schemas:calendar:dtstart XML nodes,
      ' corresponding to the calendar item locations returned in the search request.
      StartTimeNodeList = ResponseXmlDoc.GetElementsByTagName("d:dtstart")

      ' Build a list of the urn:schemas:calendar:dtend XML nodes,
      ' corresponding to the calendar item locations returned in the search request.
      EndTimeNodeList = ResponseXmlDoc.GetElementsByTagName("d:dtend")

      ' Build a list of the urn:schemas:calendar:busystatus XML nodes,
      ' corresponding to the calendar item locations returned in the search request.
      BusyStatusNodeList = ResponseXmlDoc.GetElementsByTagName("d:busystatus")

      ' Build a list of the urn:schemas:calendar:instancetype XML nodes,
      ' corresponding to the calendar item locations returned in the search request.
      InstanceTypeNodeList = ResponseXmlDoc.GetElementsByTagName("d:instancetype")

      ' Loop through the returned items (if any).
      If SubjectNodeList.Count > 0 Then

         Console.WriteLine("Calendar items...")

         Dim i As Integer
         For i = 0 To SubjectNodeList.Count - 1

            ' Display the subject.
            Console.WriteLine("  Subject:       " + SubjectNodeList(i).InnerText)

            ' Display the location.
            Console.WriteLine("  Location:      " + LocationNodeList(i).InnerText)

            ' Display the start time.
            Console.WriteLine("  Start time:    " + StartTimeNodeList(i).InnerText)

            ' Display the end time.
            Console.WriteLine("  End time:      " + EndTimeNodeList(i).InnerText)

            ' Display the busy status.
            Console.WriteLine("  Busy status:   " + BusyStatusNodeList(i).InnerText)

            ' Display the instance type.
            If InstanceTypeNodeList(i).InnerText = "0" Then
                Console.WriteLine("  Instance type: 0-Single appointment")
            ElseIf InstanceTypeNodeList(i).InnerText = "1" Then
                Console.WriteLine("  Instance type: 1-Master recurring appointment")
            ElseIf InstanceTypeNodeList(i).InnerText = "2" Then
                Console.WriteLine("  Instance type: 2-Single instance, recurring appointment")
            ElseIf InstanceTypeNodeList(i).InnerText = "3" Then
                Console.WriteLine("  Instance type: 3-Exception to a recurring appointment")
            Else
                Console.WriteLine("  Instance type: Unknown")
                Console.WriteLine("")
            End If

         Next

      Else
         Console.WriteLine("No calendar items found ...")

      End If

      ' Clean up.
      ResponseStream.Close()
      Response.Close()

   Catch ex As Exception

      ' Catch any exceptions. Any error codes from the
      ' SEARCH method requests on the server will be caught
      ' here, also.
      Console.WriteLine(ex.Message)

   End Try

End Sub

End Module

Send us your feedback about the Microsoft Exchange Server 2003 SDK.

This topic last updated: March 2004

Build: June 2007 (2007.618.1)

© 2003-2006 Microsoft Corporation. All rights reserved. Terms of use.