Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi XE7 / TIdSMTP / Unicode (https://www.delphipraxis.net/186989-delphi-xe7-tidsmtp-unicode.html)

bgeltenpoth 19. Okt 2015 13:14

Delphi XE7 / TIdSMTP / Unicode
 
Hallo,

ich versuche gerade Emails mit deutschen Umlauten (ü,ö,ä usw.) bzw. auch französischen Accents(é,û,ò usw.) in Body und Subject zu erzeugen und zu verschicken und scheitere kläglich. Ich habe schon alles an Forenbeispielen ausprobiert und scheitere trotzdem. In meinem EMail Client (Outlook) werden die besagten Zeichen dann zerschossen.

Alle Beispiele die ich bisher gefunden habe sind aber mit Delphi 2009 oder früher...Mit Delphi XEx haben wir aber Unicode Strings und an der Stelle müsste sich doch etwas ändern.
Ich benutzte die mit XE7 installierten Delphi Komponenten 10.6.1.518.

Hier ist das was ich an Code habe:

Delphi-Quellcode:
msg := TIdMessage.Create(nil);
    encoder := TBase64Encoding.Create;
    try
      // msg.Encoding := mePlainText;
      msg.Body.Add(encoder.encode(GetMsgBody(aAlarm)));
      msg.Body.Add(GetMsgBody(aAlarm));
      // msg.ContentTransferEncoding := 'BASE64';
      msg.ContentTransferEncoding := '8bit';
      // msg.ContentType := 'text/plain';
      msg.ContentType := 'Mime';
      msg.CharSet := 'UTF-8';
      // msg.Subject := '=?utf-8?b?' + encoder.Encode(GetMsgSubject(aAlarm))+ '?=';
      msg.Subject := GetMsgSubject(aAlarm);
      msg.From.Address := Params.SmtpSender;
      Destination := msg.Recipients.Add;
      Destination.Address := Params.SmtpReceiver;
      SmtpClient.connect;
      SmtpClient.Send(msg);
      SmtpClient.Disconnect();
    finally
      Begin
      msg.Free;
      encoder.Free;
      End;
    end;
Was mache ich nur falsch....vielleicht hat jemand ja eine Idee...
Die beiden Methoiden GetMsgBody und GetMsgSubject lifern jeweils einen Delphi String zurück.

Gerd01 20. Okt 2015 06:46

AW: Delphi XE7 / TIdSMTP / Unicode
 
Einen Contenttype Mime gibt es nicht. Was ist mit "Destination"?
Bereinige mal Deinen Code und schau dir Beispiele an dann klappt es vielleicht.

Darlo 20. Okt 2015 07:53

AW: Delphi XE7 / TIdSMTP / Unicode
 
Ich mache es andersherum bei einem Webservice mit utf8ToAnsi(). Probier mal AnsiToUtf8();

Sir Rufo 20. Okt 2015 08:27

AW: Delphi XE7 / TIdSMTP / Unicode
 
Liste der Anhänge anzeigen (Anzahl: 1)
Indy codiert die Nachricht von alleine - wenn man korrekt mitteilt, was man haben möchte. Es sind also keine Verrenkungen nötig.

Hier mal die entsprechende Änderung für den Email-Sender. Wie man sieht, man muss eigentlich so gut wir gar nichts machen :stupid:

Im Anhang befindet sich die EXE mit diesen Änderungen zum Ausprobieren
Delphi-Quellcode:
unit SendMail.Impl.IndySendMail;

interface

uses
  SendMail,

  System.Classes,
  System.Generics.Collections,
  System.SysUtils,

  IdBaseComponent,
  IdComponent,
  IdExplicitTLSClientServerBase,
  IdIOHandler,
  IdIOHandlerSocket,
  IdIOHandlerStack,
  IdMessage,
  IdMessageClient,
  IdSASL,
  IdSASL_CRAMBase,
  IdSASL_CRAM_MD5,
  IdSASL_CRAM_SHA1,
  IdSASLAnonymous,
  IdSASLDigest,
  IdSASLExternal,
  IdSASLLogin,
  IdSASLOTP,
  IdSASLPlain,
  IdSASLSKey,
  IdSASLUserPass,
  IdSMTP,
  IdSMTPBase,
  IdSSL,
  IdSSLOpenSSL,
  IdTCPConnection,
  IdTCPClient,
  IdUserPassProvider;

const { Ja, wir definieren Konstanten }
  ContentType_TEXT_PLAIN = 'text/plain';
  CharSet_UTF8           = 'UTF-8';

type
  TIndySendMail = class( TInterfacedObject, ISendMail )
  private
    FSMTP                    : TIdSMTP;
    FSASLAnonymous           : TIdSASLAnonymous;
    FSASLCRAMMD5              : TIdSASLCRAMMD5;
    FSASLCRAMSHA1             : TIdSASLCRAMSHA1;
    FSASLDigest              : TIdSASLDigest;
    FSASLExternal            : TIdSASLExternal;
    FSASLLogin               : TIdSASLLogin;
    FSASLOTP                 : TIdSASLOTP;
    FSASLPlain               : TIdSASLPlain;
    FSASLSKey                : TIdSASLSKey;
    FUserPassProvider        : TIdUserPassProvider;
    FSSLIOHandlerSocketOpenSSL: TIdSSLIOHandlerSocketOpenSSL;
    FMessage                 : TIdMessage;
  private
    FSync: TObject;
    procedure Configure( Configuration: TSendMailConfiguration );
  private { ISendMail }
    function GetSupportedAuthTypes: TSmtpAuthTypes;
    procedure Send( Configuration: TSendMailConfiguration; Mail: TSendMailMessage );
  public
    constructor Create;
    destructor Destroy; override;
  end;

implementation

uses
  netAlike.Utils;

{ TIndySendMail }

procedure TIndySendMail.Configure( Configuration: TSendMailConfiguration );
begin
  if not( Configuration.AuthType in GetSupportedAuthTypes )
  then
    raise ENotSupportedException.Create( 'AuthType not supported' );

  FSMTP.SASLMechanisms.Clear;

  FSMTP.AuthType := satSASL;
  FSMTP.UseEhlo := True;

  FUserPassProvider.Username := Configuration.Username;
  FUserPassProvider.Password := Configuration.Password;

  FSASLExternal.AuthorizationIdentity := Configuration.TLSCertifcateId;

  case Configuration.AuthType of
    TSmtpAuthType.None:
      FSMTP.SASLMechanisms.Add.SASL := FSASLAnonymous;
    TSmtpAuthType.Extern:
      FSMTP.SASLMechanisms.Add.SASL := FSASLExternal;
    TSmtpAuthType.MD5CR:
      FSMTP.SASLMechanisms.Add.SASL := FSASLCRAMMD5;
    TSmtpAuthType.SHA1CR:
      FSMTP.SASLMechanisms.Add.SASL := FSASLCRAMSHA1;
    TSmtpAuthType.Password:
      FSMTP.SASLMechanisms.Add.SASL := FSASLLogin;
  else
    if Configuration.AuthType in GetSupportedAuthTypes
    then
      raise ENotImplemented.Create( 'AuthType not implemented' );
  end;

  if Configuration.UseSSL
  then
    begin
      FSMTP.IOHandler := FSSLIOHandlerSocketOpenSSL;
      if Configuration.UseStartTLS
      then
        begin
          FSMTP.UseTLS := utUseExplicitTLS;
        end
      else
        begin
          FSMTP.UseTLS := utUseImplicitTLS;
        end;
    end
  else
    begin
      FSMTP.IOHandler := nil;
      FSMTP.UseTLS   := utNoTLSSupport;
    end;

  FSMTP.Host := Configuration.Host;
  FSMTP.Port := Configuration.Port;
end;

constructor TIndySendMail.Create;
begin
  FSync := TObject.Create;
  inherited;

  FSMTP                     := TIdSMTP.Create( nil );
  FSSLIOHandlerSocketOpenSSL := TIdSSLIOHandlerSocketOpenSSL.Create( FSMTP );
  FUserPassProvider         := TIdUserPassProvider.Create( FSMTP );
  FSASLExternal             := TIdSASLExternal.Create( FSMTP );
  FSASLCRAMMD5               := TIdSASLCRAMMD5.Create( FSMTP );
  FSASLCRAMSHA1              := TIdSASLCRAMSHA1.Create( FSMTP );
  FSASLDigest               := TIdSASLDigest.Create( FSMTP );
  FSASLOTP                  := TIdSASLOTP.Create( FSMTP );
  FSASLSKey                 := TIdSASLSKey.Create( FSMTP );
  FSASLLogin                := TIdSASLLogin.Create( FSMTP );
  FSASLPlain                := TIdSASLPlain.Create( FSMTP );
  FSASLAnonymous            := TIdSASLAnonymous.Create( FSMTP );
  FMessage                  := TIdMessage.Create( FSMTP );

  TEnumeratorUtil.ForEach<TIdSASLUserPass>( FSMTP,
    procedure( const c: TIdSASLUserPass )
    begin
      c.UserPassProvider := FUserPassProvider;
    end,
    function( const c: TIdSASLUserPass ): Boolean
    begin
      Result := ( c.UserPassProvider = nil );
    end, True );
end;

destructor TIndySendMail.Destroy;
begin
  FreeAndNil( FSMTP );
  inherited;
  FreeAndNil( FSync );
end;

function TIndySendMail.GetSupportedAuthTypes: TSmtpAuthTypes;
begin
  Result := [
  {} TSmtpAuthType.None,
  {} TSmtpAuthType.Extern,
  {} TSmtpAuthType.MD5CR,
  {} TSmtpAuthType.SHA1CR,
  {} TSmtpAuthType.Password ];
end;

procedure TIndySendMail.Send( Configuration: TSendMailConfiguration; Mail: TSendMailMessage );
begin
  TMonitor.Enter( FSync );
  try

    Configure( Configuration );

    FMessage.Clear;

    FMessage.From.Text          := Mail.Sender;
    FMessage.Recipients.Add.Text := Mail.Receiver;
    FMessage.Subject            := Mail.Subject;
    FMessage.ContentType        := ContentType_TEXT_PLAIN; // <- da
    FMessage.CharSet            := CharSet_UTF8; // <- da
    FMessage.Body.Text          := Mail.Body;

    FSMTP.Connect;
    try
      FSMTP.Send( FMessage );
    finally
      FSMTP.Disconnect( True );
    end;

  finally
    TMonitor.Exit( FSync );
  end;
end;

end.

bgeltenpoth 20. Okt 2015 15:54

AW: Delphi XE7 / TIdSMTP / Unicode
 
Danke, Danke, Danke für das "auf die Spur setzen"...jetzt geht es...ich war echt verzweifelt...und dann sieht man manchmal den Wald vor lauter Bäumen auch nicht...ich hatte wahrscheinlich in der Zwischenzeit auch schon mal die richtige Lösung selber gefunden. Was leider erschwerend hinzu kam war die Tatsache das die beiden Methoden GetMsgBody und GetMsgSubject zwar einen Delphi String zurück liefern...der aber aus einer mit UTF-8 codierten XML Datei stammt und von daher schon nicht korrekt war...jetzt funktioniert es mit dieser Lösung, also gaaanz einfach:

Delphi-Quellcode:
msg := TIdMessage.Create(nil);
    try
      msg.From.Address := Dmod.Params.SmtpSender;
      Destination := msg.Recipients.Add;
      Destination.Address := Dmod.Params.SmtpReceiver;
      msg.Subject :=GetMsgSubject(aAlarm);
      msg.ContentType := ContentType_TEXT_PLAIN;
      msg.CharSet := CharSet_UTF8;
      msg.Body.Text := GetMsgBody(aAlarm);
      SmtpClient.connect;
      try
        SmtpClient.Send(msg);
      finally
        SmtpClient.Disconnect(True);
      end;
    finally
      msg.Free;
    end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz