MimeKit
repository·master·Indexed 24 days ago
https://github.com/jstedfast/mimekitA 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.
What's inside MimeKit
- 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.
Check MimeKit licensing and usage in proprietary products
masterMimeKit and MailKit are completely free and open source. They are licensed under the MIT license, which allows them to be used in proprietary products.Identify attachments in a message
masterDetecting 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: attachmentheader. You can access these via:MimeMessage.Attachments2. Filtering by FileName
If mail clients do not follow standard conventions, you can treat any
MimePartthat has aFileNameset 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));Extract email addresses from From, To, and Cc headers
masterThe
From,To, andCcproperties return anInternetAddressList, which containsInternetAddressobjects. BecauseInternetAddressis 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 theMembersproperty to access the individualInternetAddressitems within the group.
Access the text or HTML body of a message
masterMimeKit provides convenience properties on the
MimeMessageclass to quickly access the text content of a message without manually traversing the MIME tree:TextBody: Returns thetext/plainversion of the message body.HtmlBody: Returns thetext/htmlversion of the message body.
Note:
HtmlBodymay be a child of amultipart/relatedcontainer 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.Use MimeReader for low-level MIME parsing
masterIntroduced in v3.0.0,MimeReaderprovides a low-level alternative toMimeParser. 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.Traverse the MIME tree of a MimeMessage
masterThe
MimeMessage.Bodyis the top-level MIME entity (usually aTextPartor aMultipart). To perform complex operations like extracting all attachments while maintaining their relationship to their parent containers, useMimeIteratorto walk the tree.To perform a simple, flat (depth-first) enumeration of all body parts, use the
BodyPartsproperty. To get only the parts explicitly marked as attachments, use theAttachmentsproperty.// 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 }Access BodyParts and Attachments as IEnumerable<MimeEntity>
masterWARNING: API BREAKING CHANGE (v1.2.5)
In version 1.2.5,
BodyPartsandAttachmentswere changed to implementIEnumerable<MimeEntity>. If you are upgrading from a version prior to 1.2.5, you must update your code to handle these collections as collections ofMimeEntityrather than their previous specific types.Anonymize MimeMessages with MimeAnonymizer
masterMimeKit 4.12.0 introduced the
MimeAnonymizerclass, which allows you to anonymizeMimeMessageobjects by removing non-syntactically relevant information.Key features include:
- Preserving specific headers: Use
MimeAnonymizer.PreserveHeadersto prevent certain headers from being anonymized (v4.13.0). - Support for specific message types: Supports
message/deliver-statusandmessage/disposition-notification(v4.13.0).
- Preserving specific headers: Use
Sign messages with ARC
masterSigning with ARC (Authenticated Received Chain) requires subclassing the
ArcSignerclass.Before signing, you must validate the existing message and produce an
ARC-Authentication-Resultsheader. TheArcSignerclass 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
AuthenticationResultsobject containing the methods used (e.g., DKIM, SPF) and their respective results.Access the body of a MimeMessage
masterMIME messages are tree structures. While you can traverse the tree manually,
MimeMessageprovides convenience properties for common text formats:TextBody: Returns thetext/plainversion of the message body.HtmlBody: Returns thetext/htmlversion of the message body.
Note:
HtmlBodymight be a child of amultipart/relatedcontainer to support embedded images. For full control over related content, manual tree traversal is recommended.Traverse the MIME tree using MimeIterator
masterTo properly handle complex MIME structures (like finding and removing attachments), use
MimeIterator. This allows you to walk the tree and access both the currentMimePartand its parentMultipartcontainer.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]);