POP: Decoding MIME-Encoded Email Messages


When retrieving messages using the POP component, emails that are more complex than plain text may appear encoded. This is because such messages are formatted using MIME (Multipurpose Internet Mail Extensions), which encapsulates attachments, HTML content, inline images, and formatting into a single encoded structure.

These messages remain in MIME format until they are decoded by a mail client. To properly process and display the message content, you must use the MIME component to decode the message into its individual parts.

MIME messages can contain multiple layers of encapsulation, so it is recommended to use a recursive routine that can process nested MIME entities. This allows all parts of the message, including embedded attachments and HTML content, to be correctly extracted.

As a starting point, you can apply such a routine to the POP component's MessageHeaders and MessageText values to decode the full message structure.

    private void MimeDecode(string entityHeaders, string entity)
    {
      var mime1 = new nsoftware.IPWorks.MIME();

      mime1.MessageHeadersString = entityHeaders;
      mime1.Message = entity;

      try
      {
        mime1.DecodeFromString();
      }
      catch
      {
        // If an error is encountered, the entity is not a valid MIME entity
        return;
      }

      for (int i = 0; i < mime1.Parts.Count; i++)
      {
        // If the Content-Type is "Multipart/????", then that part is an encoded entity
        // You will want to call this routine again
        if (mime1.Parts[i].ContentType.ToLower().StartsWith("multipart"))
        {
          MimeDecode(mime1.Parts[i].Headers, mime1.Parts[i].DecodedString);
        }

        // If a part is text/plain and is not an attachment, it is generally
        // the plain text body of the message
        if (mime1.Parts[i].FileName == "" && mime1.Parts[i].ContentType.ToLower() == "text/plain")
        {
          // Display your text here; read from mime1.Parts[i].DecodedString
        }

        // If you're going to support HTML messages, you'll want to look for this
        // part, and if found, use it in place of the plain text
        if (mime1.Parts[i].ContentType.ToLower() == "text/html")
        {
          // Again, read from mime1.Parts[i].DecodedString to access
        }

        // External attachments show up with a content-disposition of "attachment"
        if (mime1.Parts[i].ContentDisposition.ToLower() == "attachment")
        {
          // mime1.Parts[i].FileName will contain the name of the file.
          // To get the file data, read mime1.Parts[i].DecodedFile, which returns
          // the path to a temp file. Rename/move it to your desired location.
        }

        // Inline data sent in the email will generally have a content-ID header
        // and a content-disposition of "inline"
        if (mime1.Parts[i].ContentId != "")
        {
          // Treat these as external attachments. The HTML will include CID tags
          // corresponding to this data, or save as attachments if not supporting HTML.
        }
      }
    }

We appreciate your feedback. If you have any questions, comments, or suggestions about this article please contact our support team at support@nsoftware.com.