TextPart Class

A textual MIME part.

Definition

Namespace: MimeKit
Assembly: MimeKit.Core (in MimeKit.Core.dll) Version: 5.0.0
C#
public class TextPart : MimePart, ITextPart, 
	IMimePart, IMimeEntity, IDisposable
Inheritance
Object    MimeEntity    MimePart    TextPart
Implements
IMimeEntity, IMimePart, ITextPart, IDisposable

Remarks

Unless overridden, all textual parts parsed by the IMimeParser, such as text/plain or text/html, will be represented by a TextPart.

For more information about text media types, see section 4.1 of rfc2046.

Example

C#
                    /// <summary>
/// Visits a MimeMessage and generates HTML suitable to be rendered by a browser control.
/// </summary>
class HtmlPreviewVisitor : MimeVisitor
{
    List<MultipartRelated> stack = new List<MultipartRelated> ();
    List<MimeEntity> attachments = new List<MimeEntity> ();
    string body;

    /// <summary>
    /// Creates a new HtmlPreviewVisitor.
    /// </summary>
    public HtmlPreviewVisitor ()
    {
    }

    /// <summary>
    /// The list of attachments that were in the MimeMessage.
    /// </summary>
    public IList<MimeEntity> Attachments {
        get { return attachments; }
    }

    /// <summary>
    /// The HTML string that can be set on the BrowserControl.
    /// </summary>
    public string HtmlBody {
        get { return body ?? string.Empty; }
    }

    protected override void VisitMultipartAlternative (MultipartAlternative alternative)
    {
        // walk the multipart/alternative children backwards from greatest level of faithfulness to the least faithful
        for (int i = alternative.Count - 1; i >= 0 && body == null; i--)
            alternative[i].Accept (this);
    }

    protected override void VisitMultipartRelated (MultipartRelated related)
    {
        var root = related.Root;

        // push this multipart/related onto our stack
        stack.Add (related);

        // visit the root document
        root.Accept (this);

        // pop this multipart/related off our stack
        stack.RemoveAt (stack.Count - 1);
    }

    // look up the image based on the img src url within our multipart/related stack
    bool TryGetImage (string url, out MimePart image)
    {
        UriKind kind;
        int index;
        Uri uri;

        if (Uri.IsWellFormedUriString (url, UriKind.Absolute))
            kind = UriKind.Absolute;
        else if (Uri.IsWellFormedUriString (url, UriKind.Relative))
            kind = UriKind.Relative;
        else
            kind = UriKind.RelativeOrAbsolute;

        try {
            uri = new Uri (url, kind);
        } catch {
            image = null;
            return false;
        }

        for (int i = stack.Count - 1; i >= 0; i--) {
            if ((index = stack[i].IndexOf (uri)) == -1)
                continue;

            image = stack[i][index] as MimePart;
            return image != null;
        }

        image = null;

        return false;
    }

    /// <summary>
    /// Get a data: URI for the image attachment.
    /// </summary>
    /// <remarks>
    /// Encodes the image attachment into a string suitable for setting as a src= attribute value in
    /// an img tag.
    /// </remarks>
    /// <returns>The data: URI.</returns>
    /// <param name="image">The image attachment.</param>
    string GetDataUri (MimePart image)
    {
        using (var memory = new MemoryStream ()) {
            image.Content.DecodeTo (memory);
            var buffer = memory.GetBuffer ();
            var length = (int) memory.Length;
            var base64 = Convert.ToBase64String (buffer, 0, length);

            return string.Format ("data:{0};base64,{1}", image.ContentType.MimeType, base64);
        }
    }

    // Replaces <img src=...> urls that refer to images embedded within the message with
    // "file://" urls that the browser control will actually be able to load.
    void HtmlTagCallback (HtmlTagContext ctx, HtmlWriter htmlWriter)
    {
        if (ctx.TagId == HtmlTagId.Meta && !ctx.IsEndTag) {
            bool isContentType = false;

            ctx.WriteTag (htmlWriter, false);

            // replace charsets with "utf-8" since our output will be in utf-8 (and not whatever the original charset was)
            foreach (var attribute in ctx.Attributes) {
                if (attribute.Id == HtmlAttributeId.Charset) {
                    htmlWriter.WriteAttributeName (attribute.Name);
                    htmlWriter.WriteAttributeValue ("utf-8");
                } else if (isContentType && attribute.Id == HtmlAttributeId.Content) {
                    htmlWriter.WriteAttributeName (attribute.Name);
                    htmlWriter.WriteAttributeValue ("text/html; charset=utf-8");
                } else {
                    if (attribute.Id == HtmlAttributeId.HttpEquiv && attribute.Value != null
                        && attribute.Value.Equals ("Content-Type", StringComparison.OrdinalIgnoreCase))
                        isContentType = true;

                    htmlWriter.WriteAttribute (attribute);
                }
            }
        } else if (ctx.TagId == HtmlTagId.Image && !ctx.IsEndTag && stack.Count > 0) {
            ctx.WriteTag (htmlWriter, false);

            // replace the src attribute with a "data:" URL
            foreach (var attribute in ctx.Attributes) {
                if (attribute.Id == HtmlAttributeId.Src) {
                    if (!TryGetImage (attribute.Value, out var image)) {
                        htmlWriter.WriteAttribute (attribute);
                        continue;
                    }

                    var dataUri = GetDataUri (image);

                    htmlWriter.WriteAttributeName (attribute.Name);
                    htmlWriter.WriteAttributeValue (dataUri);
                } else {
                    htmlWriter.WriteAttribute (attribute);
                }
            }
        } else {
            // pass the tag through to the output
            ctx.WriteTag (htmlWriter, true);
        }
    }

    protected override void VisitTextPart (TextPart entity)
    {
        TextConverter converter;

        if (body != null) {
            // since we've already found the body, treat this as an attachment
            attachments.Add (entity);
            return;
        }

        if (entity.IsHtml) {
            converter = new HtmlToHtml {
                HtmlTagCallback = HtmlTagCallback
            };
        } else if (entity.IsFlowed) {
            var flowed = new FlowedToHtml ();
            string delsp;

            if (entity.ContentType.Parameters.TryGetValue ("delsp", out delsp))
                flowed.DeleteSpace = delsp.Equals ("yes", StringComparison.OrdinalIgnoreCase);

            converter = flowed;
        } else {
            converter = new TextToHtml ();
        }

        body = converter.Convert (entity.Text);
    }

    protected override void VisitTnefPart (TnefPart entity)
    {
        // extract any attachments in the MS-TNEF part
        using (var tnef = entity.LoadTnefMessage ()) {
            // the converted message (and its attachments) outlives the TnefMessage
            var result = tnef.ConvertToMime ();

            attachments.AddRange (result.Message.Attachments);
        }
    }

    protected override void VisitMessagePart (MessagePart entity)
    {
        // treat message/rfc822 parts as attachments
        attachments.Add (entity);
    }

    protected override void VisitMimePart (MimePart entity)
    {
        // realistically, if we've gotten this far, then we can treat this as an attachment
        // even if the IsAttachment property is false.
        attachments.Add (entity);
    }
}
                  

Constructors

TextPart Initialize a new instance of the TextPart class with a Content-Type of text/plain.
TextPart(MimeEntityConstructorArgs) Initialize a new instance of the TextPart class.
TextPart(String) Initialize a new instance of the TextPart class with the specified text subtype.
TextPart(TextFormat) Initialize a new instance of the TextPart class with the specified text format.
TextPart(String, Object) Initialize a new instance of the TextPart class with the specified text subtype.

Properties

Content Get or set the MIME content.
(Inherited from MimePart)
ContentBase Get or set the base content URI.
(Inherited from MimeEntity)
ContentDescription Get or set the description of the content if available.
(Inherited from MimePart)
ContentDisposition Get or set the content disposition.
(Inherited from MimeEntity)
ContentDuration Get or set the duration of the content if available.
(Inherited from MimePart)
ContentId Get or set the Content-Id.
(Inherited from MimeEntity)
ContentLocation Get or set the content location.
(Inherited from MimeEntity)
ContentMd5 Get or set the md5sum of the content.
(Inherited from MimePart)
ContentTransferEncoding Get or set the content transfer encoding.
(Inherited from MimePart)
ContentType Get the type of the content.
(Inherited from MimeEntity)
FileName Get or set the name of the file.
(Inherited from MimePart)
Format Get the text format of the content.
Headers Get the list of headers.
(Inherited from MimeEntity)
IsAttachment Get a value indicating whether this MimePart is an attachment.
(Inherited from MimeEntity)
IsEnriched Get whether this text part contains enriched text.
IsFlowed Get whether this text part contains flowed text.
IsHtml Get whether this text part contains HTML.
IsPlain Get whether this text part contains plain text.
IsRichText Get whether this text part contains RTF.
Text Get the decoded text content.

Methods

Accept Dispatches to the specific visit method for this MIME entity.
(Overrides MimePartAccept(MimeVisitor))
ComputeContentMd5 Compute the MD5 checksum of the content.
(Inherited from MimePart)
Dispose Releases all resources used by the MimeEntity object.
(Inherited from MimeEntity)
Dispose(Boolean) Releases the unmanaged resources used by the MimePart and optionally releases the managed resources.
(Inherited from MimePart)
Equals Determines whether the specified object is equal to the current object.
(Inherited from Object)
Finalize Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
(Inherited from Object)
GetBestEncoding(EncodingConstraint, CancellationToken) Calculate the most efficient content encoding given the specified constraint.
(Inherited from MimePart)
GetBestEncoding(EncodingConstraint, Int32, CancellationToken) Calculate the most efficient content encoding given the specified constraint.
(Inherited from MimePart)
GetHashCode Serves as the default hash function.
(Inherited from Object)
GetText(Encoding) Get the decoded text content using the provided charset encoding to override the charset specified in the Content-Type parameters.
GetText(Encoding) Get the decoded text and the encoding used to convert it into unicode.
GetText(String) Get the decoded text content using the provided charset to override the charset specified in the Content-Type parameters.
GetType Gets the Type of the current instance.
(Inherited from Object)
MemberwiseClone Creates a shallow copy of the current Object.
(Inherited from Object)
OnHeadersChanged Called when the headers change in some way.
(Inherited from MimePart)
Prepare Prepare the MIME entity for transport using the specified encoding constraints.
(Inherited from MimePart)
RemoveHeader Remove a header by name.
(Inherited from MimeEntity)
SetHeader(String, Byte) Set the value of a header using the raw value.
(Inherited from MimeEntity)
SetHeader(String, String) Set the value of a header.
(Inherited from MimeEntity)
SetText(Encoding, String) Set the text content and the charset parameter in the Content-Type header.
SetText(String, String) Set the text content and the charset parameter in the Content-Type header.
ToString Return a String that represents the MimeEntity for debugging purposes.
(Inherited from MimeEntity)
TryDetectEncoding Try to detect the encoding of the text content.
TryInit Tries to use the given object to initialize the appropriate property.
(Inherited from MimeEntity)
VerifyContentMd5 Verify the Content-Md5 value against an independently computed md5sum.
(Inherited from MimePart)
WriteTo(Stream, CancellationToken) Write the MimeEntity to the specified output stream.
(Inherited from MimeEntity)
WriteTo(String, CancellationToken) Write the MimeEntity to the specified file.
(Inherited from MimeEntity)
WriteTo(FormatOptions, Stream, CancellationToken) Write the MimeEntity to the specified output stream.
(Inherited from MimeEntity)
WriteTo(FormatOptions, String, CancellationToken) Write the MimeEntity to the specified file.
(Inherited from MimeEntity)
WriteTo(Stream, Boolean, CancellationToken) Write the MimeEntity to the specified output stream.
(Inherited from MimeEntity)
WriteTo(String, Boolean, CancellationToken) Write the MimeEntity to the specified file.
(Inherited from MimeEntity)
WriteTo(FormatOptions, Stream, Boolean, CancellationToken) Write the MimeEntity to the specified output stream.
(Inherited from MimeEntity)
WriteTo(FormatOptions, String, Boolean, CancellationToken) Write the MimeEntity to the specified file.
(Inherited from MimeEntity)
WriteToAsync(Stream, CancellationToken) Asynchronously write the MimeEntity to the specified output stream.
(Inherited from MimeEntity)
WriteToAsync(String, CancellationToken) Asynchronously write the MimeEntity to the specified file.
(Inherited from MimeEntity)
WriteToAsync(FormatOptions, Stream, CancellationToken) Asynchronously write the MimeEntity to the specified output stream.
(Inherited from MimeEntity)
WriteToAsync(FormatOptions, String, CancellationToken) Asynchronously write the MimeEntity to the specified file.
(Inherited from MimeEntity)
WriteToAsync(Stream, Boolean, CancellationToken) Asynchronously write the MimeEntity to the specified output stream.
(Inherited from MimeEntity)
WriteToAsync(String, Boolean, CancellationToken) Asynchronously write the MimeEntity to the specified file.
(Inherited from MimeEntity)
WriteToAsync(FormatOptions, Stream, Boolean, CancellationToken) Asynchronously write the MimeEntity to the specified output stream.
(Inherited from MimeEntity)
WriteToAsync(FormatOptions, String, Boolean, CancellationToken) Asynchronously write the MimeEntity to the specified file.
(Inherited from MimeEntity)

See Also

Reference