Click or drag to resize
MimeKit

TextPart Class

A Textual MIME part.
Inheritance Hierarchy

Namespace:  MimeKit
Assembly:  MimeKit (in MimeKit.dll) Version: 2.0.7.0
Syntax
C#
public class TextPart : MimePart

The TextPart type exposes the following members.

Constructors
  NameDescription
Public methodTextPart
Initializes a new instance of the TextPart class with a Content-Type of text/plain.
Public methodTextPart(String)
Initializes a new instance of the TextPart class with the specified text subtype.
Public methodTextPart(MimeEntityConstructorArgs)
Initializes a new instance of the TextPart class.
Public methodTextPart(TextFormat)
Initializes a new instance of the TextPart class with the specified text format.
Public methodTextPart(String, Object)
Initializes a new instance of the TextPart class with the specified text subtype.
Top
Properties
  NameDescription
Public propertyCode exampleContent
Gets or sets the MIME content.
(Inherited from MimePart.)
Public propertyContentBase
Gets or sets the base content URI.
(Inherited from MimeEntity.)
Public propertyContentDisposition
Gets or sets the content disposition.
(Inherited from MimeEntity.)
Public propertyContentDuration
Gets or sets the duration of the content if available.
(Inherited from MimePart.)
Public propertyContentId
Gets or sets the content identifier.
(Inherited from MimeEntity.)
Public propertyContentLocation
Gets or sets the content location.
(Inherited from MimeEntity.)
Public propertyContentMd5
Gets or sets the md5sum of the content.
(Inherited from MimePart.)
Public propertyContentObject Obsolete.
Gets or sets the MIME content.
(Inherited from MimePart.)
Public propertyContentTransferEncoding
Gets or sets the content transfer encoding.
(Inherited from MimePart.)
Public propertyContentType
Gets the type of the content.
(Inherited from MimeEntity.)
Public propertyCode exampleFileName
Gets or sets the name of the file.
(Inherited from MimePart.)
Public propertyHeaders
Gets the list of headers.
(Inherited from MimeEntity.)
Public propertyIsAttachment
Gets a value indicating whether this MimePart is an attachment.
(Inherited from MimeEntity.)
Public propertyIsEnriched
Gets whether or not this text part contains enriched text.
Public propertyCode exampleIsFlowed
Gets whether or not this text part contains flowed text.
Public propertyCode exampleIsHtml
Gets whether or not this text part contains HTML.
Public propertyIsPlain
Gets whether or not this text part contains plain text.
Public propertyIsRichText
Gets whether or not this text part contains RTF.
Public propertyText
Gets the decoded text content.
Top
Methods
  NameDescription
Public methodAccept
Dispatches to the specific visit method for this MIME entity.
(Overrides MimePartAccept(MimeVisitor).)
Public methodComputeContentMd5
Computes the MD5 checksum of the content.
(Inherited from MimePart.)
Public methodEquals
Determines whether the specified object is equal to the current object.
(Inherited from Object.)
Protected methodFinalize
Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
(Inherited from Object.)
Public methodGetBestEncoding(EncodingConstraint, CancellationToken)
Calculates the most efficient content encoding given the specified constraint.
(Inherited from MimePart.)
Public methodGetBestEncoding(EncodingConstraint, Int32, CancellationToken)
Calculates the most efficient content encoding given the specified constraint.
(Inherited from MimePart.)
Public methodGetHashCode
Serves as the default hash function.
(Inherited from Object.)
Public methodGetText(String)
Gets the decoded text content using the provided charset to override the charset specified in the Content-Type parameters.
Public methodGetText(Encoding)
Gets the decoded text content using the provided charset encoding to override the charset specified in the Content-Type parameters.
Public methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Protected methodMemberwiseClone
Creates a shallow copy of the current Object.
(Inherited from Object.)
Protected methodOnHeadersChanged
Called when the headers change in some way.
(Inherited from MimePart.)
Public methodPrepare
Prepare the MIME entity for transport using the specified encoding constraints.
(Inherited from MimePart.)
Protected methodRemoveHeader
Removes the header.
(Inherited from MimeEntity.)
Protected methodSetHeader(String, Byte)
Sets the header using the raw value.
(Inherited from MimeEntity.)
Protected methodSetHeader(String, String)
Sets the header.
(Inherited from MimeEntity.)
Public methodSetText(String, String)
Sets the text content and the charset parameter in the Content-Type header.
Public methodSetText(Encoding, String)
Sets the text content and the charset parameter in the Content-Type header.
Public methodToString
Returns a String that represents the current MimeEntity.
(Inherited from MimeEntity.)
Protected methodTryInit
Tries to use the given object to initialize the appropriate property.
(Inherited from MimeEntity.)
Public methodVerifyContentMd5
Verifies the Content-Md5 value against an independently computed md5sum.
(Inherited from MimePart.)
Public methodWriteTo(Stream, CancellationToken)
Write the MimeEntity to the specified output stream.
(Inherited from MimeEntity.)
Public methodWriteTo(String, CancellationToken)
Writes the MimeEntity to the specified file.
(Inherited from MimeEntity.)
Public methodWriteTo(Stream, Boolean, CancellationToken)
Write the MimeEntity to the specified output stream.
(Inherited from MimeEntity.)
Public methodWriteTo(String, Boolean, CancellationToken)
Write the MimeEntity to the specified file.
(Inherited from MimeEntity.)
Public methodWriteTo(FormatOptions, Stream, CancellationToken)
Write the MimeEntity to the specified output stream.
(Inherited from MimeEntity.)
Public methodWriteTo(FormatOptions, String, CancellationToken)
Write the MimeEntity to the specified file.
(Inherited from MimeEntity.)
Public methodWriteTo(FormatOptions, String, Boolean, CancellationToken)
Write the MimeEntity to the specified file.
(Inherited from MimeEntity.)
Public methodWriteTo(FormatOptions, Stream, Boolean, CancellationToken)
Writes the MimePart to the specified output stream.
(Inherited from MimePart.)
Public methodWriteToAsync(Stream, CancellationToken)
Asynchronously write the MimeEntity to the specified output stream.
(Inherited from MimeEntity.)
Public methodWriteToAsync(String, CancellationToken)
Asynchronously writes the MimeEntity to the specified file.
(Inherited from MimeEntity.)
Public methodWriteToAsync(Stream, Boolean, CancellationToken)
Adsynchronously write the MimeEntity to the specified output stream.
(Inherited from MimeEntity.)
Public methodWriteToAsync(String, Boolean, CancellationToken)
Asynchronously write the MimeEntity to the specified file.
(Inherited from MimeEntity.)
Public methodWriteToAsync(FormatOptions, Stream, CancellationToken)
Asynchronously write the MimeEntity to the specified output stream.
(Inherited from MimeEntity.)
Public methodWriteToAsync(FormatOptions, String, CancellationToken)
Asynchronously write the MimeEntity to the specified file.
(Inherited from MimeEntity.)
Public methodWriteToAsync(FormatOptions, String, Boolean, CancellationToken)
Asynchronously write the MimeEntity to the specified file.
(Inherited from MimeEntity.)
Public methodWriteToAsync(FormatOptions, Stream, Boolean, CancellationToken)
Asynchronously writes the MimePart to the specified output stream.
(Inherited from MimePart.)
Top
Remarks

Unless overridden, all textual parts parsed by the MimeParser, 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.

Examples
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> ();
    readonly string tempDir;
    string body;

    /// <summary>
    /// Creates a new HtmlPreviewVisitor.
    /// </summary>
    /// <param name="tempDirectory">A temporary directory used for storing image files.</param>
    public HtmlPreviewVisitor (string tempDirectory)
    {
        tempDir = tempDirectory;
    }

    /// <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;
    }

    // Save the image to our temp directory and return a "file://" url suitable for
    // the browser control to load.
    // Note: if you'd rather embed the image data into the HTML, you can construct a
    // "data:" url instead.
    string SaveImage (MimePart image, string url)
    {
        string fileName = url.Replace (':', '_').Replace ('\\', '_').Replace ('/', '_');

        string path = Path.Combine (tempDir, fileName);

        if (!File.Exists (path)) {
            using (var output = File.Create (path))
                image.Content.DecodeTo (output);
        }

        return "file://" + path.Replace ('\\', '/');
    }

    // 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.Image && !ctx.IsEndTag && stack.Count > 0) {
            ctx.WriteTag (htmlWriter, false);

            // replace the src attribute with a file:// URL
            foreach (var attribute in ctx.Attributes) {
                if (attribute.Id == HtmlAttributeId.Src) {
                    MimePart image;
                    string url;

                    if (!TryGetImage (attribute.Value, out image)) {
                        htmlWriter.WriteAttribute (attribute);
                        continue;
                    }

                    url = SaveImage (image, attribute.Value);

                    htmlWriter.WriteAttributeName (attribute.Name);
                    htmlWriter.WriteAttributeValue (url);
                } else {
                    htmlWriter.WriteAttribute (attribute);
                }
            }
        } else if (ctx.TagId == HtmlTagId.Body && !ctx.IsEndTag) {
            ctx.WriteTag (htmlWriter, false);

            // add and/or replace oncontextmenu="return false;"
            foreach (var attribute in ctx.Attributes) {
                if (attribute.Name.ToLowerInvariant () == "oncontextmenu")
                    continue;

                htmlWriter.WriteAttribute (attribute);
            }

            htmlWriter.WriteAttribute ("oncontextmenu", "return false;");
        } 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.ToLowerInvariant () == "yes";

            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
        attachments.AddRange (entity.ExtractAttachments ());
    }

    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);
    }
}
See Also