2017-05-05 3 views
3

Ich habe Probleme mit der E-Mail-Codierung. Ich lese eine HTML-Datei von der Festplatte und sende sie über Gmail ein. Wenn ich das HTML im Browser öffne, sieht es gut aus. Wenn ich die HTML-Zeichenfolge aus Visual Studio kopieren und als HTML-Datei speichern, sieht es gut aus. Wenn ich die E-Mail erhalte, enthält sie eine Reihe ungültiger Zeichen. Selbst die Listenkugeln sind durcheinander! Ich bin sicher, dass dies ein Problem mit der Kodierung ist, aber die Datei ist als UTF-8 kodiert und sieht gut aus, bis sie in RAW konvertiert und über Google Mail gesendet wird.HTML sieht im Browser OK aus, aber nicht in E-Mail

Hier ist der Prozess. Wir lesen von einem Dokument mit der OpenXML SDK dann verwenden wir die HtmlConverter, um das Dokument als HTML zu speichern. Später wird der HTML-Code aus der Datei eingelesen, in RAW-Formatierung konvertiert und über die GMail API gesendet.

Hier sind einige relevante Code snips:

Dies ist, wo wir unsere HTML-Datei mit HtmlConverter speichern.

HtmlConverterSettings settings = new HtmlConverterSettings() 
{ 
    AdditionalCss = "body { margin: 1cm auto; max-width: 20cm; padding: 0; }", 
    FabricateCssClasses = true, 
    RestrictToSupportedLanguages = false, 
    RestrictToSupportedNumberingFormats = false, 
}; 

XElement htmlElement = HtmlConverter.ConvertToHtml(wdWordDocument, settings); 
var html = new XDocument(
    new XDocumentType("html", null, null, null), 
    htmlElement); 

var htmlString = html.ToString(SaveOptions.DisableFormatting); 
File.WriteAllText(destFileName.FullName, htmlString, Encoding.UTF8); 

Hier lesen wir die gespeicherte HTMl und konvertieren sie für den Versand über Gmail. (Wir verwenden Mimekit für die Konvertierung.)

// Create the message using MimeKit/System.Net.Mail.MailMessage 
MailMessage msg = new MailMessage(); 
msg.Subject = strEmailSubject; // Subject 
msg.From = new MailAddress(strUserEmail); // Sender 
msg.To.Add(new MailAddress(row.email)); // Recipient 
msg.BodyEncoding = Encoding.UTF8; 
msg.IsBodyHtml = true; 

// We need to loop through our HTML Document and replace the images with a CID so that they will display inline 
var vHtmlDoc = new HtmlAgilityPack.HtmlDocument(); 
vHtmlDoc.Load(row.file); // Read the body, from HTML file 
... 
msg.Body = vHtmlDoc.DocumentNode.OuterHtml; 

// Convert our System.Net.Mail.MailMessage to RAW with Base64 encoding for Gmail 
MimeMessage mimeMessage = MimeMessage.CreateFromMailMessage(msg); 

Google.Apis.Gmail.v1.Data.Message message = new Google.Apis.Gmail.v1.Data.Message(); 
message.Raw = Base64UrlEncode(mimeMessage.ToString()); 
var result = vGMailService.Users.Messages.Send(message, "me").Execute(); 

Und das ist, wie wir Base64-Kodierung sind:

private static string Base64UrlEncode(string input) 
{ 
var inputBytes = System.Text.Encoding.UTF8.GetBytes(input); 
// Special "url-safe" base64 encode. 
return Convert.ToBase64String(inputBytes) 
        .Replace('+', '-') 
        .Replace('/', '_') 
        .Replace("=", ""); 
} 

Die E-Mail endet als "Content-Type: multipart/mixed" mit zwei Alternativen. Eine davon ist

Content-Type: text/plain; charset=UTF-8 
Content-Transfer-Encoding: quoted-printable 

und die andere

Content-Type: text/html; charset=UTF-8 
Content-Transfer-Encoding: quoted-printable 

Der sowohl der Klartext und die HTML enthalten Zeichenfolge wie = C3 = A2 = E2 = 82 = AC = E2 = 84 = A2 für einen Apostroph und der HTML-Teil enthält einen HTML-Header, der seltsame "3D" -Zeichen enthält.

Keine dieser Seltsamkeit war in der HTML vor dem Konvertieren zu Base64 und Senden.

Irgendwelche Ideen, was das Problem sein könnte? Hat das etwas mit UTF8 und Mimekit zu tun?

+0

Ich kann deine Frage nicht beantworten, aber es wird mein Vorschlag für Anstrengung. – adv12

+0

Warum ersetzen Sie Teile Ihrer Base64-Zeichenfolge? Ich verstehe nicht, was der Kommentar 'Special 'url-safe" base64 encode "bedeutet. – Equalsk

+0

Haben Sie überprüft, ob die Ausgabe von mimekit mit RFC 2822 auscheckt? Da das ist, was GMail API-Dokumente sagt, es ist erforderlich, wenn Sie mit Raw arbeiten. –

Antwort

0

Dies ist, was Ihr Code sollte die API für die Verwendung mit Google die „rohen“ Nachrichtendaten zu erhalten wie folgt aussehen:

using (var stream = new MemoryStream()) { 
    message.WriteTo (stream); 

    var buffer = stream.ToArray(); 
    var base64 = Convert.ToBase64String (buffer) 
     .Replace('+', '-') 
     .Replace('/', '_') 
     .Replace("=", ""); 

    message.Raw = base64; 
} 

Wie brandon927 wies darauf hin, der Inhalt des text/html MIME-Teil zitiert wurde -druckbar codiert. Dies ist eine MIME-Codierung, die für den Transport verwendet wird, um sicherzustellen, dass sie in den 7-Bit-ascii-Bereich passt.

Sie müssen dies decodieren, um das ursprüngliche HTML zu erhalten.

Mit MimeKit wird dies für Sie getan, wenn Sie entweder mimeMessage.HtmlBody verwenden oder wenn Sie die MimeEntity werfen, die den text/html Teil in ein TextPart und Zugriff auf die Text Eigenschaft.

+0

Vielen Dank @jstedfast! Ich habe letzte Woche Stunden damit verbracht. Ich habe die Zeile 'message.Raw = Base64UrlEncode (mimeMessage.ToString())' mit Ihrem Code ersetzt und nun werden die E-Mails korrekt in Google Mail und in meinem E-Mail-Client angezeigt. Ich hätte das wahrscheinlich nie herausgefunden. :) – mack

+0

Ehrfürchtig, froh, dass das für dich geklappt hat :) – jstedfast

0

Die Antwort auf Ihre Frage ist: Es gibt kein Problem. Dies ist einfach wie Raw präsentiert wird, mit Codierung. So präsentiert Gmail es auch, wenn Sie eine E-Mail senden und sich die Quelle ansehen.

+0

Danke @ brandon927 Also, wie würde ich gehen, um den Text richtig in der E-Mail zu zeigen? – mack

Verwandte Themen