Re: multipart/alternate clarification

Giganews Newsgroups
Subject: Re: multipart/alternate clarification
Posted by:  Remy Lebeau \(Indy Team\) (no.spam@no.spam.com)
Date: Mon, 26 Oct 2009

"Frank Bishop" <francis12…@fairpoint.net> wrote in message
news:FF027C690496E340francis12…@fairpoint.net...

> It appears to me that, while the multipart/alternate allows an html
> and a plain text message part to be delivered, some email clients
> don't implement this feature preferring to just strip out the HTML

The MIME standard dictates that "multipart/alternative" (your code is naming
the wrong Content-Type!) content must be presented in increasing order of
complexity from simpliest to most complex.  That means putting the plain
text first, and then the HTML afterwards (your code is putting them in the
reverse order instead!).  Any MIME-compliant reader must start at the last
(most complex) part and work backwards until it reaches a part that it knows
how to handle.  That way, if the reader does not want to handle HTML, it can
skip it and eventually fall back on the plain text.  If the reader does not
support MIME, then the multipart content ends up being displayed as-is, but
the least complex (plain text) part appears first so the reader still has a
chance of understanding the original message.

> code used to create the message

For newer versions of Indy 10, you should use the TIdMessageBuilderHtml
helper class that was introduced, instead of building up the TIdMessage
manually, ie:

uses
  IdMessageBuilder;

function TEmailOutgoing.CreateHTMLWithPlainAlternate : TIdMessage;
var
  Builder: TIdMessageBuilderHtml;
  sDateTime: String;
begin
  sDateTime := DateTimeToStr(Now);
  Builder := TIdMessageBuilderHtml.Create;
  try
    Builder.PlainTextCharSet := 'windows-1250';
    Builder.PlainTextContentTransfer := 'base64';
    Builder.PlainText.Add('From: ' + FServer);
    Builder.PlainText.Add('');
    Builder.PlainText.Add('This is the Plain Text Message Part');
    Builder.PlainText.Add('');
    Builder.PlainText.Add('Sent at ' + sDateTime);

    Builder.HtmlCharSet := 'windows-1250';
    Builder.HtmlContentTransfer := 'base64';
    Builder.Html.Add('<html>');
    Builder.Html.Add('<head>');
    Builder.Html.Add('<title>Title Goes here</title>');
    Builder.Html.Add('</head>');
    Builder.Html.Add('<body bgcolor="#FFE4B5">');
    Builder.Html.Add('<Center><H3>From:' + FServer + '</H3></Center>');
    Builder.Html.Add('<p>');
    Builder.Html.Add('This is the HTML Email Message Part');
    Builder.Html.Add('</p>');
    Builder.Html.Add('<p>');
    Builder.Html.Add('Sent at: ' + sDateTime);
    Builder.Html.Add('</p>');
    Builder.Html.Add('</body>');
    Builder.Html.Add('</html>');

    Result := Builder.NewMessage;
  finally
    Builder.Free;
  end;

  Result.Subject := 'Testing HTML V3.1c Email (Plain Text Alternate)';
  ...
end;

> in both outlook 2003 and thunderbird what is displayed is the
>
> This is the HTML Email Message Part
>
> when both are set for displaying emails as HTML or as Plain Text

That is because you are putting the HTML content first in the message parts
instead of last, and you are using the wrong value for the message's
Content-Type header.  As such, MIME-enabled readers will know that there are
several "multipart/" parts available, but since the Content-Type is
unrecognized, the parts must be interpret as "multipart/mixed", and as such
only the first displayable part (the HTML content) will be displayed and the
rest will be treated as extra attachments.  Since the HTML part has its own
Content-Type header, the reader knows how to render the content as HTML
correctly.

--
Remy Lebeau (TeamB)

Replies

In response to

multipart/alternate clarification posted by Frank Bishop on Mon, 26 Oct 2009