views:

335

answers:

5

I want to send a password email to a user, however the customer wants an image embedded (inline) in the email.

I created an email, saved the data to a txt file, during my code I read in the template but when I send it the line endings are broken and therefore the MIME data is broken. I just get =3D

What am I doing wrong?

    string FILENAME = Server.MapPath("~/GuestUserTemplate.txt");
    StreamReader objStreamReader = File.OpenText(FILENAME);
    string sEmailTemplate = "";
    string input = null;
    while ((input = objStreamReader.ReadLine()) != null)
    {
        sEmailTemplate = sEmailTemplate + input;
    }
    objStreamReader.Close();

    /* send an email */
    MailMessage msg = new MailMessage();
    msg.IsBodyHtml = true;
    msg.To.Add(new MailAddress(sToEmail));
    msg.From = new MailAddress(sFromEmail);
    msg.Subject = sEmailSubject;
    msg.Body = sEmailTemplate;
    //try
    {
        client.Send(msg);
    }
    //catch (Exception excm)
    {

    }

Just done a bit more detective work. The email I am sending out has this in the header:

MIME-Version: 1.0
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: quoted-printable

Where as an email which has inline images has:

Content-class: urn:content-classes:message
MIME-Version: 1.0
Content-Type: multipart/related;
    boundary="----_=_NextPart_001_01C9C98D.6552117E";
    type="multipart/alternative"

It seems that I need to set the Content type to multipart but I am not sure how...

A: 

You should use System.Net.Mail. Create a MailMessage, then add an attachment and send with SmtpClient.

Tor Haugen
He wants the image to be inlined, not show up as an attachment, so this will not work.
Oded
A: 

Check your text file - it may be missing the expected line ending (Cr + Lf).

Oded
Using Programmers Notepad I can see that the line endings are CR+LF as you would expect. I cannot see where the re-encoding is happening...
Phil Hannent
Is it an ASCII file? .NET will be using UTF-8 internally.
Oded
@Oded, Good question. Programmers Notepad reports its UTF-8... would email prefer the Unix line endings?
Phil Hannent
Not really, as it is a .NET class. But looking at your code, the while loop looks a bit suspect... doing too many things.
Oded
A: 

Change the while loop from:

while ((input = objStreamReader.ReadLine()) != null)
{
    sEmailTemplate = sEmailTemplate + input;
}

To:

sEmailTemplate = sEmailTemplate + objStreamReader.ReadToEnd();
Oded
That just gives the same result.
Phil Hannent
Are you certain your code is picking up the correct text file? Is it on the root path?
Oded
It is a fair question. Yes, I just double checked by renaming it. I was just reading the =3D is some sort of MIME encoding, I am wondering if the template is being encoded as I set it to the message body?
Phil Hannent
It would be encoded to ASCII.
Oded
A: 

The bottom line is that you can't do this with System.Net.Mail.

Here is the problem you are running into.

a) Encodings.

Your orignal mail was saved with the quoted-printable encoding (hence the "=3D"s you are seeing) When you re-read this into the message, these will get double encoded. Encodings are using for protecting the message during SMTP transport.

b)Boundaries.

When a message is created, boundaries are used in the headers to tell the mail client the boundaries of different parts of the message. You are trying to take boundaries of one message, and merge them into a new message. Since System.Net.Mail doesn't give you enough control over the internal boundaries, you can't do this.

If you want to send an embedded image using System.Net.Mail, you will need to create the message using a Linked Resource. Here is a link with more:

http://systemnetmail.com/faq/4.4.aspx

Cheers!

Dave

dave wanta
+1  A: 

I'm not quite sure what kind of text you are loading (and appending to what?) but I would recommend you create a real template, e.g. your email text with placeholders that will be replaced with user's name, etc.

Use <img src="cid:logo.png" /> - for the inline image in the HTML body of the message (in your template).

You will then need to add the corresponding image to the LinkedResources collection of the MailMessage and set its ContentID header to "logo.png" or whatever you call it. After that go and send your mail (multipart content type will be set automatically for you based on the structure of the mail message).

P.S.: use SendAsync() or write the mail to the local pickup queue of your own smtp server, otherwise you tie up your ASP.NET worker thread. Connecting to remote smtp servers/web services etc. takes a considerable amount of time (compared to the request execution time) and the worker thread is sitting there waiting and unable to service other incoming requests.

liggett78
Thank you, that worked perfectly.
Phil Hannent