Fetching a Manifest (WebDAV)

Topic Last Modified: 2006-06-12

The following examples use the SEARCH Method to fetch the Manifest of a Collection that has never been previously fetched from the server. See Client Needs to Fetch a Manifest and Authentication and Security Using WebDAV for more information.

C#

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

namespace ExchangeSDK.Snippets.CSharp
{
   class GetManifest
   {

   [STAThread]
   static void Main(string[] args)
   {
      // Variables.
      System.Net.HttpWebRequest Request;
      System.Net.WebResponse Response;
      System.Net.CredentialCache MyCredentialCache;
      string strRootURI = "https://server/TestStore/testfolder/";
      string strUserName = "User";
      string strPassword = "!Password";
      string strDomain = "Domain";
      string strSearchRequest="";
      byte[] bytes = null;
      System.IO.Stream RequestStream = null;
      System.IO.Stream ResponseStream = null;
      XmlDocument ResponseXmlDoc = null;
      System.Xml.XmlNode rootNode = null;
      System.Xml.XmlNamespaceManager nsmgr = null;
      System.Xml.XmlNode collblobNode = null;
      System.Xml.XmlNodeList ResponseNodes = null;
      string davPrefix = "";
      string replPrefix = "";

      try
      {
         // Build the search request.
         strSearchRequest = "<?xml version=\"1.0\"?>"
         + "<D:searchrequest xmlns:D = \"DAV:\" "
         + "xmlns:R=\"https://schemas.microsoft.com/repl/\" xmlns:M=\"urn:schemas:httpmail:\">"
         + "<R:repl>"
         + "<R:collblob/>"
         + "</R:repl>"
         + "<D:sql>SELECT \"DAV:displayname\", \"DAV:href\", \"urn:schemas:httpmail:size\", \"urn:schemas:httpmail:importance\", "
         + "\"https://schemas.microsoft.com/repl/resourcetag\" "
         + "FROM SCOPE ('SHALLOW TRAVERSAL OF \"" + strRootURI + "\"')"
         + "</D:sql></D: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(strRootURI),
            "NTLM",
            new System.Net.NetworkCredential(strUserName, strPassword, strDomain)
         );

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

         // Add the network credentials to the request.
         Request.Credentials = MyCredentialCache;
         Request.Headers.Add("Keep-alive", "True");

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

         // Encode the body using UTF-8.
         bytes = Encoding.UTF8.GetBytes((string)strSearchRequest);

         // 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);

         // Display the response XML body.
         //Console.WriteLine(ResponseXmlDoc.OuterXml);

         // Get the root node.
         rootNode = ResponseXmlDoc.DocumentElement;

         // Get the namespace prefixes from the DAV:multistatus node.
         davPrefix = rootNode.GetPrefixOfNamespace("DAV:");
         replPrefix = rootNode.GetPrefixOfNamespace("https://schemas.microsoft.com/repl/");

         // Create a new XmlNamespaceManager.
         nsmgr = new System.Xml.XmlNamespaceManager(ResponseXmlDoc.NameTable);

         // Add the namespaces and prefixes.
         nsmgr.AddNamespace(davPrefix, "DAV:");
         nsmgr.AddNamespace(replPrefix,"https://schemas.microsoft.com/repl/");

         // Get the collblob.
         collblobNode = rootNode.SelectSingleNode("//" + replPrefix + ":collblob", nsmgr);
         Console.WriteLine("collblob value: " + collblobNode.InnerText);
         Console.WriteLine("");

         // Build a list of the DAV:response XML nodes, corresponding to the resources
         // that have changed.
         ResponseNodes = ResponseXmlDoc.SelectNodes("//" + davPrefix + ":response", nsmgr);

         if(ResponseNodes.Count > 0)
         {
            Console.WriteLine(ResponseNodes.Count + " resources changed, deleted, or new...");

            // For each response...
            for(int i=0; i<ResponseNodes.Count; i++)
            {
               // Get the resource URL and changetype.
               System.Xml.XmlNode hrefNode = ResponseNodes[i].SelectSingleNode(davPrefix + ":href", nsmgr);
               System.Xml.XmlNode changetypeNode = ResponseNodes[i].SelectSingleNode(replPrefix + ":changetype", nsmgr);

               // Display info.
               Console.WriteLine("Resource URL: " + hrefNode.InnerText);
               Console.WriteLine("Resource changetype: " + changetypeNode.InnerText);

               // Get the DAV:propstat node(s).
               System.Xml.XmlNodeList propstatNodes = ResponseNodes[i].SelectNodes(davPrefix + ":propstat", nsmgr);

               // For each DAV:propstat node...
               for(int j=0;j<propstatNodes.Count; j++)
               {
                  // Get the status of the property retrieval.
                  System.Xml.XmlNode statusNode = propstatNodes[j].SelectSingleNode(davPrefix + ":status", nsmgr);

                  // Get the DAV:prop node(s).
                  System.Xml.XmlNode propNode = propstatNodes[j].SelectSingleNode(davPrefix + ":prop", nsmgr);
                  System.Xml.XmlNodeList propertyNodes;

                  // Display info.
                  Console.WriteLine("Status: " + statusNode.InnerText);

                  if(propNode.HasChildNodes)
                  {
                     // Get the DAV:prop node(s).
                     propertyNodes = propNode.ChildNodes;
                     foreach(System.Xml.XmlNode propertyNode in propertyNodes)
                     {
                        // Display property name.
                        Console.WriteLine("  Property name: " + propertyNode.Name);

                        // Only display property value if it was successfully retrieved.
                        if("HTTP/1.1 200 OK" == statusNode.InnerText)
                           Console.WriteLine("  Property value: " + propertyNode.InnerText);
                     }
                  }
               }

               Console.WriteLine("");
            }
         }
         else
         {
            Console.WriteLine("No response nodes 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);
      }
   }
}
}

Example

Visual Basic

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 strRootURI As String
   Dim strRequest 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 ResponseNodes As System.Xml.XmlNodeList
   Dim rootNode As System.Xml.XmlNode
   Dim nsmgr As System.Xml.XmlNamespaceManager
   Dim collblobNode As System.Xml.XmlNode
   Dim davPrefix As String
   Dim replPrefix As String

   Try
      ' Initialize variables.
      strUserName = "User"
      strPassword = "!Password"
      strDomain = "Domain"
      strRootURI = "https://server/TestStore/testfolder/"

      ' Build the SQL query.
      strRequest = "<?xml version=""1.0""?>" & _
         "<D:searchrequest xmlns:D = ""DAV:"" " & _
         "xmlns:R=""https://schemas.microsoft.com/repl/"" xmlns:M=""urn:schemas:httpmail:"">" & _
         "<R:repl>" & _
         "<R:collblob/>" & _
         "</R:repl>" & _
         "<D:sql>SELECT ""DAV:displayname"", ""DAV:href"", ""urn:schemas:httpmail:size"", ""urn:schemas:httpmail:importance"", " & _
         " ""https://schemas.microsoft.com/repl/resourcetag"" " & _
         "FROM SCOPE ('SHALLOW TRAVERSAL OF """ & strRootURI & """')" & _
         "</D:sql></D: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(strRootURI), _
         "NTLM", _
         New System.Net.NetworkCredential(strUserName, strPassword, strDomain) _
      )

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

      ' Add the network credentials to the request.
      Request.Credentials = MyCredentialCache
      Request.Headers.Add("Keep-alive", "True")

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

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

      ' 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"

      ' 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)

      ' Display the response XML body.
      'Console.WriteLine(ResponseXmlDoc.OuterXml)

      ' Get the root node.
      rootNode = ResponseXmlDoc.DocumentElement

      ' Get the namespace prefixes from the DAV:multistatus node.
      davPrefix = rootNode.GetPrefixOfNamespace("DAV:")
      replPrefix = rootNode.GetPrefixOfNamespace("https://schemas.microsoft.com/repl/")

      ' Create a new XmlNamespaceManager.
      nsmgr = New System.Xml.XmlNamespaceManager(ResponseXmlDoc.NameTable)

      ' Add the namespaces and prefixes.
      nsmgr.AddNamespace(davPrefix, "DAV:")
      nsmgr.AddNamespace(replPrefix, "https://schemas.microsoft.com/repl/")

      ' Get the collblob.
      collblobNode = rootNode.SelectSingleNode("//" + replPrefix + ":collblob", nsmgr)
      Console.WriteLine("collblob value: " + collblobNode.InnerText)
      Console.WriteLine("")

      ' Build a list of the DAV:response XML nodes, corresponding to the resources
      ' that have changed.
      ResponseNodes = ResponseXmlDoc.SelectNodes("//" + davPrefix + ":response", nsmgr)

      If ResponseNodes.Count > 0 Then

         Console.WriteLine(ResponseNodes.Count & " resources changed, deleted, or new...")

         ' For each response...
         Dim i As Integer
         For i = 0 To ResponseNodes.Count - 1

            ' Get the resource URL and changetype.
            Dim hrefNode As System.Xml.XmlNode
            Dim changetypeNode As System.Xml.XmlNode
            hrefNode = ResponseNodes(i).SelectSingleNode(davPrefix + ":href", nsmgr)
            changetypeNode = ResponseNodes(i).SelectSingleNode(replPrefix + ":changetype", nsmgr)

            ' Display info.
            Console.WriteLine("Resource URL: " + hrefNode.InnerText)
            Console.WriteLine("Resource changetype: " + changetypeNode.InnerText)

            ' Get the DAV:propstat node(s).
            Dim propstatNodes As System.Xml.XmlNodeList
            propstatNodes = ResponseNodes(i).SelectNodes(davPrefix + ":propstat", nsmgr)

            ' For each DAV:propstat node...
            Dim j As Integer
            For j = 0 To propstatNodes.Count - 1

               ' Get the status of the property retrieval.
               Dim statusNode As System.Xml.XmlNode
               statusNode = propstatNodes(j).SelectSingleNode(davPrefix + ":status", nsmgr)

               ' Get the DAV:prop node(s).
               Dim propNode As System.Xml.XmlNode
               propNode = propstatNodes(j).SelectSingleNode(davPrefix + ":prop", nsmgr)

               Dim propertyNodes As System.Xml.XmlNodeList

               ' Display info.
               Console.WriteLine("Status: " + statusNode.InnerText)

               If (propNode.HasChildNodes) Then

                  ' Get the DAV:prop node(s).
                  propertyNodes = propNode.ChildNodes
                  Dim propertyNode As System.Xml.XmlNode
                  For Each propertyNode In propertyNodes

                     ' Display property name.
                     Console.WriteLine("  Property name: " + propertyNode.Name)

                     ' Only display property value if it was successfully retrieved.
                     If "HTTP/1.1 200 OK" = statusNode.InnerText Then
                        Console.WriteLine("  Property value: " + propertyNode.InnerText)
                     End If

                  Console.WriteLine("")
               End If
      Else
         Console.WriteLine("No response nodes 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