MailBee.NET Objects 7.2

Envelope.GetEnvelopeItem Method 

Returns a reference to the specified item of the FETCH response.

public object GetEnvelopeItem(
   string name,
   bool stringsAsBytes
);

Parameters

name
The name of the specified element of the response.
stringsAsBytes
If true and the specified item was not recognized by MailBee as predefined object, all strings within the item data will be returned as byte arrays; if false, all strings in a non-predefined object will be returned as String.

Return Value

If the specified item was found in the response data, the method returns a reference to the object representing this item; otherwise, the method returns a null reference (Nothing in Visual Basic).

Remarks

This method can return objects of many different types depending on whether the specified item is predefined and whether it's a list of sub-items or a single item. In particular, if certain item is predefined (such as BODYSTRUCTURE, UID, FLAGS, RFC822.SIZE, etc) the corresponding object or value type will be returned (such as ImapBodyStructure, Int64, MessageFlagSet, Int32, etc).

If name is not recognized, the method returns ArrayList object if the item is a list of sub-items, or byte[]/string depending on stringsAsBytes value. In the case if ArrayList is returned, its sub-items will conform the same rule: if sub-item is a list, it will be returned as ArrayList, otherwise, byte[] or string. Thus, GetEnvelopeItem method allows the developer to examine both simple FETCH items and complex nested structures with unlimited depth of hierarchy.

The common use of setting stringsAsBytes to true is when the application needs the item data as byte array. Otherwise, the developer should set stringsAsBytes to false.

The developer can use this method to obtain user-specified items of the FETCH response (for instance, the common use is getting certain MIME part of the message). To have the particular item listed in the FETCH response, the developer should first specify its key in extraItems parameter of DownloadEnvelopes method.

If you need to extract different items for different e-mails, you can either call DownloadEnvelopes method multiple times specifying different items each time or use DownloadEnvelopesEx method. DownloadEnvelopesEx is faster as it executes as a single command (pipelining mode). The difference is especially noticable if you download many small items.

Note   Keys to be specified in extraItems parameters of DownloadEnvelopes method can be different from their corresponding item names in FETCH responses. For instance, if BODY.PEEK[1] was requested, its name in the FETCH response would be BODY[1]. See IMAP4 protocol specification (RFC3501) for more information regarding FETCH requests and responses.

Exceptions

Exception TypeCondition
MailBeeInvalidArgumentExceptionname is a null reference (Nothing in Visual Basic).

Example

This sample completely downloads all image files attached or embedded into the last message in the inbox, and saves them into C:\Temp folder. The IMAP4 server is queried twice: first, we download the body structure of the message to learn which parts as images, and then we download these parts. The entire message itself is not downloaded.

To demonstrate that key names in FETCH requests and FETCH responses can be different, this sample downloads images in read-only mode (BODY.PEEK is used instead of BODY). Thus, running this sample won't cause the server to set "\Seen" flag for the message.

This sample can extract items for one message per command If you want to use it with multiple messages, see more advanced samples in DownloadEnvelopesEx and BeginDownloadEnvelopesEx topics. Also, that advanced samples show how to extract text bodies (not only attachments).

[C#]
using System;
using MailBee;
using MailBee.ImapMail;
using MailBee.Mime;

class Sample
{
    static void Main(string[] args)
    {
        Imap imp = new Imap();

        // Connect to the server, login and select inbox.
        imp.Connect("imap.company.com");
        imp.Login("jdoe", "secret");
        imp.SelectFolder("INBOX");

        // Download body structure.
        EnvelopeCollection envs = imp.DownloadEnvelopes(imp.MessageCount.ToString(), false,
            EnvelopeParts.BodyStructure, 0);

        // The list of FETCH keys to request from the server.
        System.Collections.ArrayList fetchRequestKeys = new System.Collections.ArrayList();

        // The list of FETCH keys to expect from the server in return to the request of
        // items listed in fetchRequestKeys.
        System.Collections.ArrayList fetchResponseKeys = new System.Collections.ArrayList();

        // UID of the message for which we received the body structure.
        long uid = 0;

        if (envs.Count > 0)
        {
            Envelope env = envs[0];

            // Get body structures of all MIME parts as flat list.
            ImapBodyStructureCollection parts = env.BodyStructure.GetAllParts();
            foreach (ImapBodyStructure part in parts)
            {
                if (part.ContentType.ToLower().IndexOf("image/") > -1)
                {
                    // For each image, we request its MIME part header and body
                    // (the IMAP4 protocol does not support getting the entire MIME
                    // part as a single block of data). Also note using .MIME instead of .HEADER
                    // because some mail servers don't support .HEADER syntax.
                    fetchRequestKeys.Add("BODY.PEEK[" + part.PartID + ".MIME]");
                    fetchRequestKeys.Add("BODY.PEEK[" + part.PartID + "]");

                    // For BODY.PEEK[...] request the server will return BODY[...] response.
                    fetchResponseKeys.Add("BODY[" + part.PartID + ".MIME]");
                    fetchResponseKeys.Add("BODY[" + part.PartID + "]");
                }
            }

            // Second time, we'll get message by its UID. This will avoid the situation
            // when new message arrives between two queries (and thus it could be possible
            // to download wrong message second time).
            uid = env.Uid;
        }

        if (uid > 0)
        {
            // Download images.
            envs = imp.DownloadEnvelopes(uid.ToString(), true,
                EnvelopeParts.Uid, 0, null,
                (string[])fetchRequestKeys.ToArray(typeof(string)));

            if (envs.Count > 0)
            {
                Envelope env = envs[0];

                for (int i = 0; i < fetchRequestKeys.Count; i += 2)
                {
                    // Get MIME part header data.
                    byte[] mimePartHeader = (byte[])env.GetEnvelopeItem(
                        (string)fetchResponseKeys[i], true);

                    // Get MIME part body data.
                    byte[] mimePartBody = (byte[])env.GetEnvelopeItem(
                        (string)fetchResponseKeys[i + 1], true);

                    // Build MIME part data from header data and body data.
                    byte[] mimePartData = new byte[mimePartHeader.Length + mimePartBody.Length];
                    Buffer.BlockCopy(mimePartHeader, 0, mimePartData, 0, mimePartHeader.Length);
                    Buffer.BlockCopy(mimePartBody, 0, mimePartData,
                        mimePartHeader.Length, mimePartBody.Length);
                    mimePartHeader = null;
                    mimePartBody = null;

                    // Build Attachment object from the MIME part data.
                    MimePart part = MimePart.Parse(mimePartData);
                    Attachment picture = new Attachment(part);

                    // Save the image into C:\Temp folder.
                    picture.SaveToFolder(@"C:\Temp", false);
                }
            }
        }

        imp.Disconnect();
    }
}
[Visual Basic]
Imports System
Imports MailBee
Imports MailBee.ImapMail
Imports MailBee.Mime

Module Sample
    Sub Main(ByVal args As String())
        Dim imp As New Imap

        ' Connect to the server, login and select inbox.
        imp.Connect("imap.company.com")
        imp.Login("jdoe", "secret")
        imp.SelectFolder("INBOX")

        ' Download body structure.
        Dim envs As EnvelopeCollection = imp.DownloadEnvelopes(imp.MessageCount.ToString(), _
            False, EnvelopeParts.BodyStructure, 0)

        ' The list of FETCH keys to request from the server.
        Dim fetchRequestKeys As New System.Collections.ArrayList

        ' The list of FETCH keys to expect from the server in return to the request of
        ' items listed in fetchRequestKeys.
        Dim fetchResponseKeys As New System.Collections.ArrayList

        ' UID of the message for which we received the body structure.
        Dim uid As Long = 0
        If envs.Count > 0 Then
            Dim env As Envelope = envs(0)

            ' Get body structures of all MIME parts as flat list.
            Dim parts As ImapBodyStructureCollection = env.BodyStructure.GetAllParts()
            For Each part As ImapBodyStructure In parts
                If part.ContentType.ToLower().IndexOf("image/") > -1 Then
                    ' For each image, we request its MIME part header and body
                    ' (the IMAP4 protocol does not support getting the entire MIME
                    ' part as a single block of data). Also note using .MIME instead of .HEADER
                    ' because some mail servers don't support .HEADER syntax.
                    fetchRequestKeys.Add("BODY.PEEK[" & part.PartID & ".MIME]")
                    fetchRequestKeys.Add("BODY.PEEK[" & part.PartID & "]")

                    ' For BODY.PEEK[...] request the server will return BODY[...] response.
                    fetchResponseKeys.Add("BODY[" & part.PartID & ".MIME]")
                    fetchResponseKeys.Add("BODY[" & part.PartID & "]")
                End If
            Next

            ' Second time, we'll get message by its UID. This will avoid the situation
            ' when new message arrives between two queries (and thus it could be possible
            ' to download wrong message second time).
            uid = env.Uid
        End If

        If uid > 0 Then
            ' Download images.
            envs = imp.DownloadEnvelopes(uid.ToString(), True, EnvelopeParts.Uid, 0, _
                Nothing, CType(fetchRequestKeys.ToArray(GetType(String)), String()))

            If envs.Count > 0 Then
                Dim env As Envelope = envs(0)

                Dim i As Integer
                For i = 0 To fetchRequestKeys.Count - 1 Step 2
                    ' Get MIME part header data.
                    Dim mimePartHeader, mimePartBody As Byte()
                    mimePartHeader = env.GetEnvelopeItem(CType(fetchResponseKeys(i), String), True)

                    ' Get MIME part body data.
                    mimePartBody = env.GetEnvelopeItem(CType(fetchResponseKeys(i + 1), String), True)

                    ' Build MIME part data from header data and body data.
                    Dim mimePartData As Byte()
                    ReDim mimePartData(mimePartHeader.Length + mimePartBody.Length)
                    Buffer.BlockCopy(mimePartHeader, 0, mimePartData, 0, mimePartHeader.Length)
                    Buffer.BlockCopy(mimePartBody, 0, mimePartData, mimePartHeader.Length, mimePartBody.Length)
                    mimePartHeader = Nothing
                    mimePartBody = Nothing

                    ' Build Attachment object from the MIME part data.
                    Dim part As MimePart = MimePart.Parse(mimePartData)
                    Dim picture As New Attachment(part)

                    ' Save the image into C:\Temp folder.
                    picture.SaveToFolder("C:\Temp", False)
                Next
            End If
        End If

        imp.Disconnect()
    End Sub
End Module

See Also

Envelope Class | MailBee.ImapMail Namespace | DownloadEnvelopes