MimeKit

repository·master·Indexed 24 days ago

https://github.com/jstedfast/mimekit

A high-performance C# library for creating and parsing MIME messages, designed as a robust implementation of IETF MIME specifications for the .NET ecosystem. It provides APIs for parsing email messages from streams or files, traversing MIME trees, and creating complex messages using the BodyBuilder class. The library also includes support for S/MIME and PGP/MIME encryption, decryption, and digital signing.

Tokens
18.9K
Snippets
43
Records
99
Agent score
83%

What's inside MimeKit

  1. What is MimeKit?

    master
    MimeKit is a C# library designed for the creation and parsing of email messages using the Multipurpose Internet Mail Extension (MIME) format. It follows IETF specifications closely and provides a high-level API for .NET developers.
  2. Identify attachments in a message

    master

    Detecting attachments can be done in several ways depending on how strictly you want to follow MIME conventions:

    1. Using the standard Attachments property

    Most messages use the Content-Disposition: attachment header. You can access these via: MimeMessage.Attachments

    2. Filtering by FileName

    If mail clients do not follow standard conventions, you can treat any MimePart that has a FileName set as an attachment:

    var attachments = message.BodyParts.OfType<MimePart>().Where(part => !string.IsNullOrEmpty(part.FileName));

    3. Advanced: Identifying unreferenced parts

    A more sophisticated approach is to treat any body part that is not used for rendering the main textual body as an attachment.

    var attachments = message.BodyParts.OfType<MimePart> ().Where (part => !string.IsNullOrEmpty (part.FileName));
  3. Extract email addresses from From, To, and Cc headers

    master

    The From, To, and Cc properties return an InternetAddressList, which contains InternetAddress objects. Because InternetAddress is an abstract class, you must check the specific subclass to access the actual email address.

    • MailboxAddress: The most common type, representing a single email address (e.g., user@example.com).
    • GroupAddress: Represents a named group of addresses. You must iterate through the Members property to access the individual InternetAddress items within the group.
  4. Access the text or HTML body of a message

    master

    MimeKit provides convenience properties on the MimeMessage class to quickly access the text content of a message without manually traversing the MIME tree:

    • TextBody: Returns the text/plain version of the message body.
    • HtmlBody: Returns the text/html version of the message body.

    Note: HtmlBody may be a child of a multipart/related container to allow for embedded images. While convenient, these properties are not a substitute for full MIME tree traversal if you need to properly handle related content or media.

  5. Use MimeReader for low-level MIME parsing

    master
    Introduced in v3.0.0, MimeReader provides a low-level alternative to MimeParser. It allows you to parse MIME content without instantiating a full MIME tree of objects or waiting for the entire parser to complete before processing data. This approach is conceptually similar to a SAX XML parser, making it suitable for high-performance or streaming scenarios where you want to process parts of a message as they are encountered.
  6. Traverse the MIME tree of a MimeMessage

    master

    The MimeMessage.Body is the top-level MIME entity (usually a TextPart or a Multipart). To perform complex operations like extracting all attachments while maintaining their relationship to their parent containers, use MimeIterator to walk the tree.

    To perform a simple, flat (depth-first) enumeration of all body parts, use the BodyParts property. To get only the parts explicitly marked as attachments, use the Attachments property.

    // Deep traversal using MimeIterator to find and remove attachments
    var attachments = new List<MimePart> ();
    var multiparts = new List<Multipart> ();
    var iter = new MimeIterator (message);
    
    while (iter.MoveNext ()) {
        var multipart = iter.Parent as Multipart;
        var part = iter.Current as MimePart;
    
        if (multipart != null && part != null && part.IsAttachment) {
            multiparts.Add (multipart);
            attachments.Add (part);
        }
    }
    
    for (int i = 0; i < attachments.Count; i++)
        multiparts[i].Remove (attachments[i]);
    
    // Quick flat enumeration of all parts
    foreach (var part in message.BodyParts) {
       // do something
    }
    
    // Quick enumeration of only attachments
    foreach (var attachment in message.Attachments) {
       // do something
    }
  7. Access BodyParts and Attachments as IEnumerable<MimeEntity>

    master

    WARNING: API BREAKING CHANGE (v1.2.5)

    In version 1.2.5, BodyParts and Attachments were changed to implement IEnumerable<MimeEntity>. If you are upgrading from a version prior to 1.2.5, you must update your code to handle these collections as collections of MimeEntity rather than their previous specific types.

  8. Anonymize MimeMessages with MimeAnonymizer

    master

    MimeKit 4.12.0 introduced the MimeAnonymizer class, which allows you to anonymize MimeMessage objects by removing non-syntactically relevant information.

    Key features include:

    • Preserving specific headers: Use MimeAnonymizer.PreserveHeaders to prevent certain headers from being anonymized (v4.13.0).
    • Support for specific message types: Supports message/deliver-status and message/disposition-notification (v4.13.0).
  9. Sign messages with ARC

    master

    Signing with ARC (Authenticated Received Chain) requires subclassing the ArcSigner class.

    Before signing, you must validate the existing message and produce an ARC-Authentication-Results header. The ArcSigner class requires you to override one of the following methods to provide the authentication results:

    • GenerateArcAuthenticationResults: For synchronous signing.
    • GenerateArcAuthenticationResultsAsync: For asynchronous signing.

    These methods should return an AuthenticationResults object containing the methods used (e.g., DKIM, SPF) and their respective results.

  10. Access the body of a MimeMessage

    master

    MIME messages are tree structures. While you can traverse the tree manually, MimeMessage provides convenience properties for common text formats:

    • TextBody: Returns the text/plain version of the message body.
    • HtmlBody: Returns the text/html version of the message body.

    Note: HtmlBody might be a child of a multipart/related container to support embedded images. For full control over related content, manual tree traversal is recommended.

  11. Traverse the MIME tree using MimeIterator

    master

    To properly handle complex MIME structures (like finding and removing attachments), use MimeIterator. This allows you to walk the tree and access both the current MimePart and its parent Multipart container.

    var attachments = new List<MimePart> ();
    var multiparts = new List<Multipart> ();
    var iter = new MimeIterator (message);
    
    // collect our list of attachments and their parent multiparts
    while (iter.MoveNext ()) {
        var multipart = iter.Parent as Multipart;
        var part = iter.Current as MimePart;
    
        if (multipart != null && part != null && part.IsAttachment) {
            // keep track of each attachment's parent multipart
            multiparts.Add (multipart);
            attachments.Add (part);
        }
    }
    
    // now remove each attachment from its parent multipart...
    for (int i = 0; i < attachments.Count; i++)
        multiparts[i].Remove (attachments[i]);