Enumerating Message Attachments (WebDAV)

Topic Last Modified: 2006-06-12

The following example uses the X-MS-ENUMATTS Method to enumerate the attachments of an e-mail message.

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.

Example

VBScript

Example

Option Explicit

' variables
dim req                         ' As MSXML2.XMLHTTP
dim strURI                      ' As String
Dim resDoc                      ' As Msxml2.DOMDocument
Dim objPropstatNodeList         ' As IXMLDOMNodeList
Dim objHrefNodeList             ' As IXMLDOMNodeList
Dim objPropstatNode             ' As IXMLDOMNode
Dim objStatusNode               ' As IXMLDOMNode
Dim objHrefNode                 ' As IXMLDOMNode
Dim objNode                     ' As IXMLDOMNode
Dim i                           ' As Integer

' The URI of the e-mail message.
strURI = "https://server/exchange/username/inbox/TestMessage.eml/"

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

' Specify the X-MS-ENUMATTS method, the URI of the e-mail message, that the
' request will be sent synchronously, the username, and password.
req.open "X-MS-ENUMATTS", strURI, false, "Domain\username", "!Password"

' Send the X-MS-ENUMATTS request.
req.send

' The request was not successful.
If req.status > 207 Or req.status < 207 Then
    wscript.echo "Status: " & req.status
    wscript.echo "Status text: " & req.statustext
    wscript.echo "Response text: " & req.responsetext

' The request was successful.
Else
    wscript.echo "Status: " & req.status
    wscript.echo "Status text: " & req.statustext

    ' Uncomment this line to display the XML response body.
    'wscript.echo "Response text: " & req.responsetext
    wscript.echo ""

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

    ' Build a list of the DAV:propstat XML nodes, corresponding to the
    ' returned status and properties of the file attachment(s). The
    ' DAV: namespace is typically assigned the a: prefix in
    ' the XML response body. The namespaceses and their associated
    ' prefixes are listed in the attributes of the DAV:multistatus node
    ' of the XML response.
    Set objPropstatNodeList = resDoc.getElementsByTagName("a:propstat")

    ' Build a list of the DAV:href nodes, corresponding to the URIs of
    ' the attachement(s) on the message.  For each DAV:href node in the
    ' XML response, there is an associated DAV:propstat node.
    Set objHrefNodeList = resDoc.getElementsByTagName("a:href")

    If objPropstatNodeList.length > 0 Then

        ' Display the number of attachments on the message.
        wscript.echo objPropstatNodeList.length & " attachments found..."

        ' Iterate through the attachment properties.
        For i = 0 To (objPropstatNodeList.length -1)

            ' Get the next DAV:propstat node in the node list.
            set objPropstatNode = objPropstatNodeList.nextNode

            ' Get the next DAV:href node in the node list.
            set objHrefNode = objHrefNodeList.nextNode

            ' Use an XPath query to get the DAV:status node from the DAV:propstat node.
            set objStatusNode = objPropstatNode.selectSingleNode("a:status")

            ' Check the status of the attachment properties.
            If Not objStatusNode.Text = "HTTP/1.1 200 OK" Then
                wscript.echo "Attachment: " &  objHrefNode.Text
                wscript.echo "Status: " & objStatusNode.Text
                wscript.echo ""

            Else
                wscript.echo "Attachment: " &  objHrefNode.Text
                wscript.echo "Status: " & objStatusNode.Text

                ' Get the CdoPR_ATTACH_FILENAME_W MAPI property tag,
                ' corresponding to the attachment file name.  The
                ' https://schemas.microsoft.com/mapi/proptag/ namespace is typically
                ' assigned the d: prefix in the XML response body.
                set objNode = objPropstatNode.selectSingleNode("a:prop/d:x3704001f")
                wscript.echo "Attachment name: " & objNode.Text

                ' Get the CdoPR_ATTACH_EXTENSION_W MAPI property tag,
                ' corresponding to the attachment file extension.
                set objNode = objPropstatNode.selectSingleNode("a:prop/d:x3703001f")
                wscript.echo "File extension: " & objNode.Text

                ' Get the CdoPR_ATTACH_SIZE MAPI property tag,
                ' corresponding to the attachment file size.
                set objNode = objPropstatNode.selectSingleNode("a:prop/d:x0e200003")
                wscript.echo "Attachment size: " & objNode.Text & " bytes"

                wscript.echo ""

            End If
    Else
        wscript.echo "No file attachments found..."
    End If

End If

' Clean up.
Set req = Nothing
Set resDoc = Nothing
Set objPropstatNodeList = Nothing
Set objHrefNodeList = Nothing
Set objPropstatNode = Nothing
Set objHrefNode = Nothing
Set objStatusNode = Nothing
Set objNode = Nothing

C#

Example

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

namespace ExchangeSDK.Snippets.CSharp
{
   class EnumeratingAttachmentsWebDAV
   {
      [STAThread]
      static void Main(string[] args)
      {
         // Variables.
         System.Net.HttpWebRequest Request;
         System.Net.WebResponse Response;
         System.Net.CredentialCache MyCredentialCache;
         string strMessageURI = "https://server/exchange/username/inbox/TestMessage.eml/";
         string strUserName = "username";
         string strPassword = "!Password";
         string strDomain = "Domain";
         System.IO.Stream ResponseStream = null;
         System.Xml.XmlDocument ResponseXmlDoc = null;
         System.Xml.XmlNode root = null;
         System.Xml.XmlNamespaceManager nsmgr = null;
         System.Xml.XmlNodeList PropstatNodes = null;
         System.Xml.XmlNodeList HrefNodes = null;
         System.Xml.XmlNode StatusNode = null;
         System.Xml.XmlNode PropNode = null;

         try
         {
            // 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(strMessageURI),
               "NTLM",
               new System.Net.NetworkCredential(strUserName, strPassword, strDomain)
               );

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

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

            // Specify the method.
            Request.Method = "X-MS-ENUMATTS";

            // Send the X-MS-ENUMATTS 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 System.Xml.XmlDocument();

            // Load the XML response stream.
            ResponseXmlDoc.Load(ResponseStream);

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

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

            // Add the DAV: namespace, which is typically assigned the a: prefix
            // in the XML response body.  The namespaceses and their associated
            // prefixes are listed in the attributes of the DAV:multistatus node
            // of the XML response.
            nsmgr.AddNamespace("a", "DAV:");

            // Add the https://schemas.microsoft.com/mapi/proptag/ namespace, which
            // is typically assigned the d: prefix in the XML response body.
            nsmgr.AddNamespace("d", "https://schemas.microsoft.com/mapi/proptag/");

            // Use an XPath query to build a list of the DAV:propstat XML nodes,
            // corresponding to the returned status and properties of
            // the file attachment(s).
            PropstatNodes = root.SelectNodes("//a:propstat", nsmgr);

            // Use an XPath query to build a list of the DAV:href nodes,
            // corresponding to the URIs of the attachement(s) on the message.
            // For each DAV:href node in the XML response, there is an
            // associated DAV:propstat node.
            HrefNodes = root.SelectNodes("//a:href", nsmgr);

            // Attachments found?
            if(HrefNodes.Count > 0)
            {
               // Display the number of attachments on the message.
               Console.WriteLine(HrefNodes.Count + " attachments found...");

               // Iterate through the attachment properties.
               for(int i=0;i<HrefNodes.Count;i++)
               {
                  // Use an XPath query to get the DAV:status node from the DAV:propstat node.
                  StatusNode = PropstatNodes[i].SelectSingleNode("a:status", nsmgr);

                  // Check the status of the attachment properties.
                  if(StatusNode.InnerText != "HTTP/1.1 200 OK")
                  {
                     Console.WriteLine("Attachment: " + HrefNodes[i].InnerText);
                     Console.WriteLine("Status: " + StatusNode.InnerText);
                     Console.WriteLine("");
                  }
                  else
                  {
                     Console.WriteLine("Attachment: " + HrefNodes[i].InnerText);
                     Console.WriteLine("Status: " + StatusNode.InnerText);

                     // Get the CdoPR_ATTACH_FILENAME_W MAPI property tag,
                     // corresponding to the attachment file name.  The
                     // https://schemas.microsoft.com/mapi/proptag/ namespace is typically
                     // assigned the d: prefix in the XML response body.
                     PropNode = PropstatNodes[i].SelectSingleNode("a:prop/d:x3704001f", nsmgr);
                     Console.WriteLine("Attachment name: " + PropNode.InnerText);

                     // Get the CdoPR_ATTACH_EXTENSION_W MAPI property tag,
                     // corresponding to the attachment file extension.
                     PropNode = PropstatNodes[i].SelectSingleNode("a:prop/d:x3703001f", nsmgr);
                     Console.WriteLine("File extension: " + PropNode.InnerText);

                     // Get the CdoPR_ATTACH_SIZE MAPI property tag,
                     // corresponding to the attachment file size.
                     PropNode = PropstatNodes[i].SelectSingleNode("a:prop/d:x0e200003", nsmgr);
                     Console.WriteLine("Attachment size: " + PropNode.InnerText);

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

            // Clean up.
            ResponseStream.Close();
            Response.Close();

         }
         catch(Exception ex)
         {
            // Catch any exceptions. Any error codes from the X-MS-ENUMATTS
            // method request on the server will be caught here, also.
            Console.WriteLine(ex.Message);
         }
      }
   }
}

Visual Basic .NET

Example

Option Explicit On
Option Strict On

Module Module1

   Sub Main()

   ' Variables.
   Dim Request As System.Net.HttpWebRequest
   Dim Response As System.Net.WebResponse
   Dim MyCredentialCache As System.Net.CredentialCache
   Dim strMessageURI As String
   Dim strUserName As String
   Dim strPassword As String
   Dim strDomain As String
   Dim ResponseStream As System.IO.Stream
   Dim ResponseXmlDoc As System.Xml.XmlDocument
   Dim root As System.Xml.XmlNode
   Dim nsmgr As System.Xml.XmlNamespaceManager
   Dim PropstatNodes As System.Xml.XmlNodeList
   Dim HrefNodes As System.Xml.XmlNodeList
   Dim StatusNode As System.Xml.XmlNode
   Dim PropNode As System.Xml.XmlNode

   ' Initialize strings.
   strMessageURI = "https://server/exchange/username/inbox/TestMessage.eml/"
   strUserName = "username"
   strPassword = "!Password"
   strDomain = "Domain"

   Try
      ' 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(strMessageURI), _
         "NTLM", _
         New System.Net.NetworkCredential(strUserName, strPassword, strDomain) _
         )

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

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

      ' Specify the X-MS-ENUMATTS method.
      Request.Method = "X-MS-ENUMATTS"

      ' Send the X-MS-ENUMATTS 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

      ' Load the XML response stream.
      ResponseXmlDoc.Load(ResponseStream)

      ' Get the root node.
      root = ResponseXmlDoc.DocumentElement

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

      ' Add the DAV: namespace, which is typically assigned the a: prefix
      ' in the XML response body.  The namespaceses and their associated
      ' prefixes are listed in the attributes of the DAV:multistatus node
      ' of the XML response.
      nsmgr.AddNamespace("a", "DAV:")

      ' Add the https://schemas.microsoft.com/mapi/proptag/ namespace, which
      ' is typically assigned the d: prefix in the XML response body.
      nsmgr.AddNamespace("d", "https://schemas.microsoft.com/mapi/proptag/")

      ' Use an XPath query to build a list of the DAV:propstat XML nodes,
      ' corresponding to the returned status and properties of
      ' the file attachment(s).
      PropstatNodes = root.SelectNodes("//a:propstat", nsmgr)

      ' Use an XPath query to build a list of the DAV:href nodes,
      ' corresponding to the URIs of the attachement(s) on the message.
      ' For each DAV:href node in the XML response, there is an
      ' associated DAV:propstat node.
      HrefNodes = root.SelectNodes("//a:href", nsmgr)

      ' Attachments found?
      If HrefNodes.Count > 0 Then
         ' Display the number of attachments on the message.
         Console.WriteLine(HrefNodes.Count & " attachments found...")

         ' Iterate through the attachment properties.
         Dim i As Integer
         For i = 0 To HrefNodes.Count - 1

            ' Use an XPath query to get the DAV:status node from the DAV:propstat node.
            StatusNode = PropstatNodes(i).SelectSingleNode("a:status", nsmgr)

            ' Check the status of the attachment properties.
            If Not StatusNode.InnerText = "HTTP/1.1 200 OK" Then

               Console.WriteLine("Attachment: " & HrefNodes(i).InnerText)
               Console.WriteLine("Status: " & StatusNode.InnerText)
               Console.WriteLine("")

            Else

               Console.WriteLine("Attachment: " & HrefNodes(i).InnerText)
               Console.WriteLine("Status: " & StatusNode.InnerText)

               ' Get the CdoPR_ATTACH_FILENAME_W MAPI property tag,
               ' corresponding to the attachment file name.  The
               ' https://schemas.microsoft.com/mapi/proptag/ namespace is typically
               ' assigned the d: prefix in the XML response body.
               PropNode = PropstatNodes(i).SelectSingleNode("a:prop/d:x3704001f", nsmgr)
               Console.WriteLine("Attachment name: " & PropNode.InnerText)

               ' Get the CdoPR_ATTACH_EXTENSION_W MAPI property tag,
               ' corresponding to the attachment file extension.
               PropNode = PropstatNodes(i).SelectSingleNode("a:prop/d:x3703001f", nsmgr)
               Console.WriteLine("File extension: " & PropNode.InnerText)

               ' Get the CdoPR_ATTACH_SIZE MAPI property tag,
               ' corresponding to the attachment file size.
               PropNode = PropstatNodes(i).SelectSingleNode("a:prop/d:x0e200003", nsmgr)
               Console.WriteLine("Attachment size: " & PropNode.InnerText)

               Console.WriteLine("")
            End If

      Else
         Console.WriteLine("No attachments found.")
      End If

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

      Catch ex As Exception

         ' Catch any exceptions. Any error codes from the X-MS-ENUMATTS
         ' method request on the server will be caught here, also.
         Console.WriteLine(ex.Message)

      End Try

   End Sub

End Module