Fetching an Updated Manifest After Some Items Have Been Processed
Fetching an Updated Manifest After Some Items Have Been Processed
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.
The following examples use the SEARCH Method to fetch the updated Manifest of a Collection from the server after some resources have been processed by the client. The collblob and resourcetag values were obtained previously when the Manifest of a Collection was first requested. See Client Has Processed Some Items and Needs 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 GetUpdatedManifestAfterProcessingSome { class GetUpdatedManifestAfterProcessingSome { [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 and resourcetag values were 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>toCTAAMAAAAJPX5nufJB ... TpL2AAAHkJaBFAA</R:collblob>" + "<R:resourcetaglist>" + "<R:resourcetag>rt:093d7e67b9f2414e92f6035970f ... 4e92f6035970fd562f000000001e55</R:resourcetag>" + "<R:resourcetag>rt:093d7e67b9f2414e92f6035970f ... 7dac2121298374752f000000001e59</R:resourcetag>" + "</R:resourcetaglist>" + "</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 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); } } } }
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 and resourcetag values were 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:resourcetaglist>" & _ "<R:resourcetag>rt:093d7e67b9f2414e92f603597 ... fd562f000000001e55</R:resourcetag>" & _ "<R:resourcetag>rt:093d7e67b9f2414e92f603597 ... fd562f000000001e59</R:resourcetag>" & _ "</R:resourcetaglist>" & _ "</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 Next Console.WriteLine("") End If Next Next 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
Send us your feedback about the Microsoft Exchange Server 2003 SDK.
This topic last updated: December 2004
Build: June 2007 (2007.618.1)
© 2003-2006 Microsoft Corporation. All rights reserved. Terms of use.