'Sending e-mail with Indy doesn't show attachment in Outlook
I have the following problem. I've created a Windows service that sends e-mail with .xls
attachments. If I open the e-mail with Windows Live Mail or Web Mail, it works, I can see the attachment. The problem happens when I try to open the e-mail with Microsoft Outlook 2010, the attachment is not present and I have no idea what's wrong with my code.
E-mail header looks like this
Return-Path: <[email protected]>
Delivered-To: [email protected]
Received: (qmail 25352 invoked by uid 500); 15 Jul 2015 14:58:23 -0000
Received: by simscan 1.4.0 ppid: 25345, pid: 25349, t: 0.0443s
scanners: attach: 1.4.0 clamav: 0.98.5/m:
Received: from unknown (HELO ab-c11) ([email protected]@111.111.111.111)
by mail.absoft.ro with ESMTPA; 15 Jul 2015 14:58:22 -0000
From: "[email protected]" <[email protected]>
Subject: Test Report
To: "Test test" <[email protected]>
Content-Type: Multipart/Alternative; boundary="wm32hkCMsS=_xUqKLF1OiOMUAOi7ru4ljM"
MIME-Version: 1.0
Date: Wed, 15 Jul 2015 17:58:21 +0300
The code I use for generating the e-mail is
ExecReport;
var
tMess: TIdMessage;
q: TADOQuery;
Attachment: TIdAttachment;
idtTextPart: TIdText;
fileAttach: string;
subiect: string;
i : Integer;
fName : string;
begin
// FEventLogger.LogMessage( ' Executing ' + IntToStr(FTask.FTaskID) , EVENTLOG_ERROR_TYPE , 0, 2);
//
tMess := TIdMessage.Create;
tMess.Subject := FTask.FDenumire;
tMess.ContentType := 'text/html';
try
q := TADOQuery.Create(nil);
q.Connection := fConn;
q.CommandTimeout := FTask.FTimeout;
q.SQL.Text := FTask.FQueryString;
q.Open;
q.First;
except
on E: Exception do
begin
FEventLogger.LogMessage(' Error! ' + E.Message,
EVENTLOG_ERROR_TYPE, 0, 2);
q.Free;
LogErrorExecution(E.Message);
Exit;
end;
end;
Subiect := FTask.FDenumire;
// dtSource := TDataSource.Create(nil);
// dtSource.dataset := q;
fileAttach := CreateExcelDocument(q,False);
tMess := TIdMessage.Create;
tMess.Clear;
tMess.ContentType := 'Multipart/Alternative';
tMess.Subject := subiect;
idtTextPart := TIdText.Create(tMess.MessageParts, nil);
idtTextPart.ContentType := 'text/plain';
idtTextPart.Body.Add(' ');
idtTextPart := TIdText.Create(tMess.MessageParts, nil);
idtTextPart.ContentType := 'text/html';
Attachment := TIdAttachmentFile.Create(tMess.MessageParts, fileAttach);
if q.RecordCount > 0 then
begin
idtTextPart.Body.Text := '<html><body bgcolor="#DCEEFC">';
if (FTask.FHeaderID <> '') then
begin
idtTextPart.Body.Text := idtTextPart.Body.Text + BuildTable(q);
end;
idtTextPart.Body.Text := idtTextPart.Body.Text + ' </body></html>';
self.SendMail(s, tMess);
end;
q.Close;
q.Free;
end;
Solution 1:[1]
How can the content type be "Multipart/Alternative" if you have an attachment? Outlook has no idea what your xls file is, so it picks up the body part that it knows about - plain text or HTML and discards the body flavor that it does not understand (xls).
Have you tried "multipart/mixed" contents type? This way you will signal to Outlook that your xls file is an attachment and has nothing to do with the message body.
UPDATE
If you want both plain text/html parts and an attachment, you message structure should be
multipart/mixed
multipart/related
text/plain
text/html
attachment
Look at the MIME structure that Outlook creates for various messages - you can see it in OutlookSpy (I am its author) - select a message similar to what you want, click IConverterSession button on the OutlookSpy toolbar, then MAPIToMIMEStm.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Dmitry Streblechenko |