Benutzer mit den meisten Antworten
MailMessage-Klasse verwenden, um ein HTML-Mail mit Images zu erstellen

Frage
-
Hallo
Ich hätte eine Frage zum Erstellen von Mails aus einer WinForm-C#-Anwendung.
Die Applikation hat bisher schon Mails mit der MailMessage-Klasse erstellen, und versenden via der SmtpClient-Klasse können. Jetzt gibt es die Erweiterung den Mail-Text auf Html-Basis zu verwenden. Eingebunden wurde Word als Editor - und vor dem Versenden wird das Word-Dokument als "HTM" gespeichert und in das Mail übernommen.
Funktioniert grundsätzlich!
ABER - wenn in dem Word/Html-Text Bilder/Images eingebunden werden, dass sieht das im Mail beim Empfänger so aus, dass das Bild als Anhang im Mail ist, und an der Stelle wo das Bild eingebunden war steht ein rotes "X" mit dem Text "Das verknüpfte Bild kann nicht angezeigt werden. Möglicherweise wurde die Datei umbenannt, verschoben oder gelöscht ...."
Ich habe jetzt noch ein paar Hinweise gefunden, einen AlternateView zu verwenden - was ich probiert hätte
// Create AlternateView for HTML-Text: AlternateView htmlView = AlternateView.CreateAlternateViewFromString(s, ct); htmlView.TransferEncoding = TransferEncoding.SevenBit; //Creating AlternateView for Plain Text Mail: AlternateView normalView = AlternateView.CreateAlternateViewFromString(s, null, "text/plain"); mail.AlternateViews.Clear(); mail.AlternateViews.Add(normalView); mail.AlternateViews.Add(htmlView);
aber nicht zum gewünscht Erfolg geführt hat.
Meine Frage nun - wie muss ich korrekt vorgehen, damit im Mail-Body der Html-Text inklusive Bild richtig beim Empfänger dargestellt wird ??
Kann mir dazu bitte jemand weiterhelfen.
Vielen Dank schon mal & schönen Gruß
Michael
Michael Erlinger
Antworten
-
Hallo Michael,
So ohne weiteres wird das nicht gehen. Normalerweise würde man einem HTML-AlternateView eine LinkedResource für jedes Bild hinzufügen, das man anhängen möchte (ContentId nicht vergessen) und im HTML-Code würde man dann über source="cid:[vergebene ContentId]" darauf hinweisen, aber die Verwendung von Word als vorgeschalteten Editor macht einige Vorarbeiten notwendig.
Beim Speichern eines Word-Dokumentes, z.B. Test.doc als "Webseite" (WdSaveFormat.wdFormatHTML) oder als "Webseite, gefiltert" (WdSaveFormat.wdFormatFilteredHTML) erstellt Word ein HTML-Dokument Test.htm das je nach gewählter Option die ursprüngliche Formatierung des Word-Dokuments mehr oder weniger getreu beibehält.
Word legt die verwendeten Bilddateien in einem Verzeichnis ab, dessen Name aus dem Dokumentnamen + dem Suffix "-Dateien" besteht. Word ändert dabei den Namen jeder Bilddatei entspr. dem Muster image001.jpg, wobei 00N einem internen Zähler entspricht. Diese Dateien werden dann im erstellten HTML-Dokument relativ zum Speicherort der HTML-Datei angegeben. Bei Verwendung von:var fileFormat = Word.WdSaveFormat.wdFormatFilteredHTML; document.SaveAs2(htmFileName, fileFormat);
findet man die relative Angabe in folgendem Format wieder:<img width=150 height=129 id="Grafik 1" src="test-Dateien/image001.jpg">
Nun muß man noch diese relativen Pfade durch eine entspr. CID ersetzen und die richtigen Dateien anhängen. Hier ein Beispiel, das ich kurz getestet habe (Office 2010, .NET 4.0, VS2010):using System; using System.IO; using System.Net; using System.Net.Mail; using System.Net.Mime; using System.Text; using System.Threading; using System.Windows.Forms; using Word = Microsoft.Office.Interop.Word; namespace HtmlMailDemo { public partial class Form1 : Form { private const string userName = "..."; private const string password = "..."; private const string mailFrom = userName; private const string mailTo = "..."; private const string picturePath = @"C:\Users\[Username]\Pictures\Compass1.jpg"; public Form1() { InitializeComponent(); } private void createHtmlMailThenSend_Click(object sender, EventArgs e) { // Word-Dokument erstellen Word.Application wordApp = new Word.Application { Visible = true }; Word.Document wordDoc = wordApp.Documents.Add(); Word.Selection selection = wordApp.Selection; selection.TypeText("Text mit Bildern (HTML).\r\n"); selection.InlineShapes.AddPicture(picturePath, false, true); // Word-Dokument als HTML-Dokument exportieren var desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); var htmFile = Path.Combine(desktopPath, "test.htm"); wordDoc.SaveAs2(htmFile, Word.WdSaveFormat.wdFormatFilteredHTML); wordDoc.Close(false); // Word beenden. Auf Freigabe aller gehaltenen Handles warten wordApp.Quit(false); Thread.Sleep(1500); // Mail-Nachricht erstellen using (MailMessage mail = new MailMessage(mailFrom, mailTo)) { mail.Subject = "HTM-Test"; // Text-Ansicht erstellen AlternateView textView = AlternateView.CreateAlternateViewFromString("Nur Text-Version."); // HTML-Ansicht anhand des exportierten HTML-Dokuments erstellen. Zunächst // muss die originale (relative) Pfadangabe durch eine Content-ID ersetzt // werden. var htmlText = File.ReadAllText(htmFile); var adjustedHtmlText = htmlText.Replace(@"test-Dateien/image001.jpg", "cid:image001"); AlternateView htmView = AlternateView.CreateAlternateViewFromString(adjustedHtmlText, UTF8Encoding.UTF8, "text/html"); // Eine verknüpfte Ressource erstellen. Die Ausgangsdatei liegt im "test-Dateien"-Ordner. // Selbe ContentId wie oben vergeben. using (LinkedResource linkedResource = new LinkedResource(@"C:\Users\[Username]\Desktop\test-Dateien\image001.jpg", new ContentType("image/jpeg"))) { linkedResource.ContentId = "image001"; linkedResource.TransferEncoding = TransferEncoding.Base64; htmView.LinkedResources.Add(linkedResource); // Text- und HTML-Ansichten zur Nachricht hinzufügen. mail.AlternateViews.Add(textView); mail.AlternateViews.Add(htmView); // Mail über SMTP versenden. using (SmtpClient smtp = new SmtpClient("...")) { smtp.Credentials = new NetworkCredential(userName, password); smtp.Send(mail); } } } } } }
Schönen GrußMarcel
- Als Antwort markiert M.Erlinger Montag, 24. September 2012 18:33
Alle Antworten
-
Hallo Michael,
So ohne weiteres wird das nicht gehen. Normalerweise würde man einem HTML-AlternateView eine LinkedResource für jedes Bild hinzufügen, das man anhängen möchte (ContentId nicht vergessen) und im HTML-Code würde man dann über source="cid:[vergebene ContentId]" darauf hinweisen, aber die Verwendung von Word als vorgeschalteten Editor macht einige Vorarbeiten notwendig.
Beim Speichern eines Word-Dokumentes, z.B. Test.doc als "Webseite" (WdSaveFormat.wdFormatHTML) oder als "Webseite, gefiltert" (WdSaveFormat.wdFormatFilteredHTML) erstellt Word ein HTML-Dokument Test.htm das je nach gewählter Option die ursprüngliche Formatierung des Word-Dokuments mehr oder weniger getreu beibehält.
Word legt die verwendeten Bilddateien in einem Verzeichnis ab, dessen Name aus dem Dokumentnamen + dem Suffix "-Dateien" besteht. Word ändert dabei den Namen jeder Bilddatei entspr. dem Muster image001.jpg, wobei 00N einem internen Zähler entspricht. Diese Dateien werden dann im erstellten HTML-Dokument relativ zum Speicherort der HTML-Datei angegeben. Bei Verwendung von:var fileFormat = Word.WdSaveFormat.wdFormatFilteredHTML; document.SaveAs2(htmFileName, fileFormat);
findet man die relative Angabe in folgendem Format wieder:<img width=150 height=129 id="Grafik 1" src="test-Dateien/image001.jpg">
Nun muß man noch diese relativen Pfade durch eine entspr. CID ersetzen und die richtigen Dateien anhängen. Hier ein Beispiel, das ich kurz getestet habe (Office 2010, .NET 4.0, VS2010):using System; using System.IO; using System.Net; using System.Net.Mail; using System.Net.Mime; using System.Text; using System.Threading; using System.Windows.Forms; using Word = Microsoft.Office.Interop.Word; namespace HtmlMailDemo { public partial class Form1 : Form { private const string userName = "..."; private const string password = "..."; private const string mailFrom = userName; private const string mailTo = "..."; private const string picturePath = @"C:\Users\[Username]\Pictures\Compass1.jpg"; public Form1() { InitializeComponent(); } private void createHtmlMailThenSend_Click(object sender, EventArgs e) { // Word-Dokument erstellen Word.Application wordApp = new Word.Application { Visible = true }; Word.Document wordDoc = wordApp.Documents.Add(); Word.Selection selection = wordApp.Selection; selection.TypeText("Text mit Bildern (HTML).\r\n"); selection.InlineShapes.AddPicture(picturePath, false, true); // Word-Dokument als HTML-Dokument exportieren var desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); var htmFile = Path.Combine(desktopPath, "test.htm"); wordDoc.SaveAs2(htmFile, Word.WdSaveFormat.wdFormatFilteredHTML); wordDoc.Close(false); // Word beenden. Auf Freigabe aller gehaltenen Handles warten wordApp.Quit(false); Thread.Sleep(1500); // Mail-Nachricht erstellen using (MailMessage mail = new MailMessage(mailFrom, mailTo)) { mail.Subject = "HTM-Test"; // Text-Ansicht erstellen AlternateView textView = AlternateView.CreateAlternateViewFromString("Nur Text-Version."); // HTML-Ansicht anhand des exportierten HTML-Dokuments erstellen. Zunächst // muss die originale (relative) Pfadangabe durch eine Content-ID ersetzt // werden. var htmlText = File.ReadAllText(htmFile); var adjustedHtmlText = htmlText.Replace(@"test-Dateien/image001.jpg", "cid:image001"); AlternateView htmView = AlternateView.CreateAlternateViewFromString(adjustedHtmlText, UTF8Encoding.UTF8, "text/html"); // Eine verknüpfte Ressource erstellen. Die Ausgangsdatei liegt im "test-Dateien"-Ordner. // Selbe ContentId wie oben vergeben. using (LinkedResource linkedResource = new LinkedResource(@"C:\Users\[Username]\Desktop\test-Dateien\image001.jpg", new ContentType("image/jpeg"))) { linkedResource.ContentId = "image001"; linkedResource.TransferEncoding = TransferEncoding.Base64; htmView.LinkedResources.Add(linkedResource); // Text- und HTML-Ansichten zur Nachricht hinzufügen. mail.AlternateViews.Add(textView); mail.AlternateViews.Add(htmView); // Mail über SMTP versenden. using (SmtpClient smtp = new SmtpClient("...")) { smtp.Credentials = new NetworkCredential(userName, password); smtp.Send(mail); } } } } } }
Schönen GrußMarcel
- Als Antwort markiert M.Erlinger Montag, 24. September 2012 18:33