Fetching an Updated Manifest (WebDAV)
Topic Last Modified: 2006-06-12
The following examples use the SEARCH Method to fetch the updated Manifest of a Collection from the server. The collblob value was obtained previously when the Manifest of a Collection was first requested. See Client Needs to Fetch an Updated 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 GetUpdatedManifest
{
[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. The collblob value was obtained previously when
// the manifest for the collection was first requested.
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>toCTAAMAAAAJPX5nufJBTpL2A1l ... BQAAAAAcQkYcUAABAAUAAAAAHkJaBFAA</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("Resource 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 changetype: " + changetypeNode.InnerText);
// DAV:href isn't returned for deleted resources.
if(hrefNode != null)
Console.WriteLine("Resource URL: " + hrefNode.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. The collblob value was obtained previously when
' the manifest for the collection was first requested.
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>toCTAAMAAAAJPX5nufJBTpL2A1l ... BQAAAAAcQkYcUAABAAUAAAAAHkJaBFAA</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 changetype: " + changetypeNode.InnerText)
' DAV:href isn't returned for deleted resources.
If Not hrefNode Is Nothing Then
Console.WriteLine("Resource URL: " + hrefNode.InnerText)
End If
' 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