Question

I am writing a system to send out bulk emails to clients and for each site we store an HTML and Text version of the email so that if the users mail client doesn't support HTML the text view is still formatted correctly and as we want.

We don't want to just generate the plain text version from the HTML version as it adds in lots of menu links and other text which isn't formatted as we want.

This works fine in ASP classic with the Persits Email Component = http://www.aspemail.com/ as we add the HTML string as the Body and the text string as the AltBody.

However I am having trouble replicating this in C# .NET 4.5

I have followed as many examples as possible but my method that returns the MailMessage object which needs to pass the HTML looking for images/banners and then replace the URLS with ContentIDs and LinkedResources is somehow returning an email that looks great in HTML and Simple HTML View (in Thunderbird).

However whatever I do the plain text view seems to always be a version of the HTML that the object is trying to convert into text RATHER than the textual string we have pre-formatted and want to use.

If I debug the code I can see that the string is correct before I add it to the alternative view so I don't know what else I need to do.

In my method that parses the HTML, adds linked resources and returns a MailMessage object I have the following code:

<pre>
/* I pass in a custom SiteEmail object with 2 properties HTMLEmail and TextEmail that hold both versions of the email */
public MailMessage ParseEmailImages(SiteEmail siteEmail)
{
    MailMessage email = new MailMessage();

    // extract the HTML version as we need to parse it to swap URLs for ContentID/Resources and paths etc
    string HTML = siteEmail.HTMLEmail;

    // this is a generic list to hold all my picture resource objects that I find (swapping image URLs to paths and contentIDs)
    List<LinkedResource> pictureResources = new List<LinkedResource>(); 


    // code to find all the paths, create image resource objects and add them to my list - and modify the HTML to reference
    // the new ContentIDs I swap the URLs for so the images are embedded in the email
    // ..... code .....

    // finished finding resource objects build email parts and return to caller

    // Add each alternate view to the message.

    // add the HTML view using my newly parsed HTML string
    ContentType HtmlContentType = new ContentType("text/html; charset=UTF-8");
    AlternateView altViewHTML = AlternateView.CreateAlternateViewFromString(HTML, HtmlContentType);
    altViewHTML.TransferEncoding = TransferEncoding.QuotedPrintable;

    // when I check here the siteEmail.TextEmail holds the CORRECT textual string I want BUT it's not displaying in the sent email

    ContentType PlainContentType = new ContentType("text/plain; charset=UTF-8");

    // as we didn't need to change anything in the text view we can just reference it straight out my custom email object siteEmail
    AlternateView altViewText = AlternateView.CreateAlternateViewFromString(siteEmail.TextEmail, PlainContentType);
    altViewText.TransferEncoding = TransferEncoding.QuotedPrintable;

    // loop through all my picture resource objects and ensure they are embedded into the HTML email
    foreach (LinkedResource pictureResource in pictureResources)
    {
        pictureResource.TransferEncoding = TransferEncoding.Base64;
        altViewHTML.LinkedResources.Add(pictureResource);
    }



    // add both parts of the email (text/html) which are both alternative views to message
    email.AlternateViews.Add(altViewText);
    email.AlternateViews.Add(altViewHTML);



    // return email object
    return email;
}


// a very cut down example of the calling method
public bool SendEmail()
{
    // parse our email object
    MailMessage EmailMailMessage = this.ParseEmailImages(this.SiteEmail);

    // send email
    EmailMailMessage.From = new MailAddress(this.SendFromEmail, this.SendFromName);

    EmailMailMessage.Subject = this.SendSubject;

    // ensure encoding is correct for Arabic/Japanese sites and body transfer method is correct
    EmailMailMessage.BodyEncoding = Encoding.UTF8;
        EmailMailMessage.BodyTransferEncoding = TransferEncoding.QuotedPrintable;

        SmtpClient client = new SmtpClient();

    // this in a try catch and more complex
    client.Send(this.EmailMailMessage);

}
</pre>

I have tried playing about with the encoding formats, just adding one alternative view and so on but cannot seem to get it to send out the same email as my old ASP Classic code e.g a multipart email with 2 boundaries, 1 for the text version WE WANT TO USE and one with the HTML version. It always seems to create it's own Plain Text version from the HTML version which I don't want to happen.

Any help or ideas would be much appreciated.

Thanks in advance for any help!

Was it helpful?

Solution

The answer seems to be that there is a bug in the MailMessage class. I have been told to report this as such on the Microsoft .NET forum.

It seems that the issue lies in the use of LinkedResources.

If I remove the code that adds the LinkedResources to the HTML alternative view then the code works fine and I can see both my Plain Text and HTML views in my mail client.

Therefore I have to leave the images as externally linked resources that are loaded into the email when the user presses any "load remote content" button in their email client.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top