4

次のコードを使用してメッセージを評価します。INDY 10 コンポーネントで受信した電子メール メッセージの内容 (本文/行)

function LinesFromMsg(aMsg: TIdMessage): TStrings; 
var
  i: Integer; 
begin
  for i := 0 to aMsg.MessageParts.AttachmentCount-1 do
  begin
    if (amsg.MessageParts.Items[i].ContentType ='HTML') then
    begin
      if (amsg.MessageParts.Items[i] is Tidtext) then
        Result := TidText(amsg.MessageParts.Items[i]).body;
    end;
  end; 
end;

このコードに関して、2 つの質問があります。

a) これは任意のメール メッセージで Tlines 部分を見つける正しい方法ですか? ( INDY 10 EMAIL MSG PARTSに示されているアドバイスを考慮してください)

b) すべての異なる Contenttype 文字列値のチュートリアルはどこにありますか?

4

1 に答える 1

8

ContentType探す正しい値は ですtext/html。値には、比較で無視する必要がある追加の属性が関連付けられている可能性があるため、 Indy のIsHeaderMediaType()関数を使用してチェックします。ContentType

TIdMessage.ContentTypeHTML メールは MIME でエンコードされていない可能性があり、したがって TIdMessage.MessageParts` コレクションをまったく使用しない可能性があるため、これも考慮する必要があります。

MessageParts.Count最後に、プロパティの代わりにプロパティを使用する必要がありMessageParts.AttachmentsCountます。

これを試して:

function HTMLFromMsg(aMsg: TIdMessage): TStrings; 
var
  i: Integer; 
  Part: TIdMessagePart;
begin
  Result := nil;
  if IsHeaderMediaType(aMsg.ContentType, 'text/html') then
  begin
    Result := aMsg.Body;
    Exit;
  end;
  for i := 0 to aMsg.MessageParts.Count-1 do
  begin
    Part := aMsg.MessageParts.Items[i];
    if (Part is TIdText) and IsHeaderMediaType(Part.ContentType, 'text/html') then
    begin
      Result := TIdText(Part).Body;
      Exit;
    end;
  end; 
end;

そうは言っても、これは技術的に MIME を処理する正しい方法ではありません。公式には、MIME パーツは最も単純な形式から最も複雑な形式に向かって下向きに並べられるため、適合するリーダーは MIME パーツを逆方向にループすることになっています。そのため、MIME のネストを考慮して逆方向にループし、サポートする最も複雑なフォームを探します。このようなもの(テストされていません):

procedure DisplayPlainText(Body: TStrings);
begin
  // display plain text as needed...
end;

procedure DisplayHTML(Body: TStrings);
begin
  // display html as needed...
end;

procedure DisplayMultiPartAlternative(aMsg: TIdMessage; aParentIndex, aLastIndex: Integer);
var
  Part: TIdMessagePart;
  i: Integer:
begin
  for i := aLastIndex-1 downto aParentIndex+1 do
  begin
    Part := aMsg.MessageParts.Items[i];
    if (Part.ParentPart = aParentIndex) and (Part is TIdText) then
    begin
      if IsHeaderMediaType(Part.ContentType, 'text/html') then
      begin
        DisplayHTML(TIdText(Part).Body);
        Exit;
      end;
      if IsHeaderMediaType(Part.ContentType, 'text/plain') then
      begin
        DisplayPlainText(TIdText(Part).Body);
        Exit;
      end;
    end;
  end;
  // nothing supported to display...
end;

procedure DisplayMultiPartMixed(aMsg: TIdMessage; aParentIndex, aLastIndex: Integer);
var
  Part: TIdMessagePart;
  i: Integer;
begin
  for i := aLastIndex-1 downto aParentIndex+1 do
  begin
    Part := aMsg.MessageParts.Items[i];
    if (Part.ParentPart = aParentIndex) and (Part is TIdText) then
    begin
      if IsHeaderMediaType(Part.ContentType, 'multipart/alternative') then
      begin
        DisplayMultiPartAlternative(aMsg, ParentPart.Index, aLastIndex);
        Exit;
      end;
      if IsHeaderMediaType(ParentPart.ContentType, 'text/html') then
      begin
        DisplayHTML(TIdText(Part).Body);
        Exit;
      end;
      if IsHeaderMediaType(Part.ContentType, 'text/plain') then
      begin
        DisplayPlainText(TIdText(Part).Body);
        Exit;
      end;
      aLastIndex := i;
    end;
  end;
  // nothing supported to display...
end;

procedure DisplayMsg(aMsg: TIdMessage); 
var
  ContentType: string;
begin
  ContentType := ExtractHeaderMediaType(aMsg.ContentType);
  case PosInStrArray(ContentType, ['multipart/mixed', 'multipart/alternative', 'text/html', 'text/plain'], False) of
    0: begin
      DisplayMultiPartAlternative(aMsg, -1, aMsg.MessageParts.Count);
      Exit;
    end;
    1: begin
      DisplayMultiPartMixed(aMsg, -1, aMsg.MessageParts.Count);
      Exit;
    end;
    2: begin
      DisplayHTML(aMsg.Body);
      Exit;
    end;
    3: begin
      DisplayPlainText(aMsg.Body);
      Exit;
    end;
  else
    // nothing supported to display...
  end;
end;
于 2013-02-03T12:21:17.730 に答える