I have an issue where I'm sending a PDF file as an attachment, but when the email arrives with the client, it's arriving as a file with a name very similar to the MIME type, but with the correct content. I specify an attachment file name of "Statement.pdf", but it arrives as "application_pdf.txt" which then confuses the receiver as it doesn't open as a PDF. The mail sending is handled by a Windows Service written in Visual Basic.
Here is the main bit of code that actually sends it:
Dim SmtpServer As New SmtpClient()
Dim mail As New MailMessage()
SmtpServer.Credentials = New Net.NetworkCredential(mailAddress, mailPassword)
SmtpServer.Port = mailPort
SmtpServer.Host = mailServer
SmtpServer.EnableSsl = mailSSL
SmtpServer.DeliveryMethod = SmtpDeliveryMethod.Network
mail = New MailMessage()
If fromName <> "" Then mailName = fromName
mail.From = New MailAddress(fromAddr, mailName)
mail.IsBodyHtml = True
mail.To.Add(toAddr)
If replyTo <> "" Then
mail.ReplyToList.Add(replyTo)
End If
If cc <> "" Then
mail.CC.Add(cc)
End If
mail.Subject = subject
mail.Body = body
If attached <> "" And attachMIME <> "" And attachname <> "" Then
mail.Attachments.Add(Attachment.CreateAttachmentFromString(attached, attachMIME))
mail.Attachments.Last().ContentDisposition.FileName = attachname
End If
SmtpServer.Send(mail)
The various variables in here are passed in from the calling code and I'm confident that they're correct, in that if the password, port etc were incorrect the email wouldn't send. In particular the attachMIME
is "application/pdf" which appears to be correct according to pdfa.org.
The PDF is generated on another machine, and passed to this one using FTP in binary mode. This service then reads the PDF into a string and passes it into the mail sending function:
Dim attachBytes() As Byte = Nothing
attachBytes = My.Computer.FileSystem.ReadAllBytes(FileDir & "\" & msg.attachFile)
mailAttachFile = ""
For Each attbyt As Byte In attachBytes
mailAttachFile &= Chr(attbyt)
Next
I thought I'd cracked it because I was originally using ReadAllText
which strips out any non-printable characters, and I imagined that the mail transport somewhere was checking the PDF for validity, seeing the unprintable characters had changed and presuming it was some sort of mal-formed file. Unfortunately changing to ReadAllBytes
didn't seem to help, and the PDF file is still arriving as a file named "attachment_pdf.txt", still with the correct content. If I save the file from my email client and then rename it, it displays perfectly as a PDF in Acrobat Reader. My customer is receiving emails from other companies with PDF attachments, so it's not just that his email provider doesn't trust PDFs.
I don't simply use AddAttachment(filename)
to load the attachment because the code works in two ways - one where the service downloads the email files from a remote FTP server, and the other (this one) where the files are sent to the machine running the service and the service opens them locally. In order to keep the actual mail sending the same, loading the files is done further "up" the code and the resulting email message and attachment passed in here via a function call. So by the time I get to the first code block I posted above, the code doesn't know (or care) where the message and attachment came from.
Is there anything glaringly obvious in what I have posted that might be causing this issue? I should add that I have the same code running on another machine, using gmail as the mail transport (which this one does not) and the other method I mentioned above and it sends a PDF attachment every day without issue.
(Edited to clarify that the attachment file contents are not changing, just the attachment name is changing, which confuses the receiver.)