V práci jsme nedávno aktualizovali HTML online editor pro vytváření obsahu emailů - přešli jsme na CK editor.
Po nasazení se nám ozval jeden z uživatelů, že někteří příjemci jeho emailů dostali email divně naformátovaný - například se jim nezobrazili obrázky či některé odkazy byly podtržené, i když dle deklarace stylu neměly být apod.
A tak začalo pátrání, co za to může. Samozřejmě prvním podezřelým byl CK editor, ale výstup, který generoval byl v pořádku. Jeho výstupní HMTL kód byl validní.
Mezitím se také zjistilo, že problémy se správným zobrazením měli jen příjemci s poštovní schránkou na AOL. Ostatním se email vždy zobrazil dobře.
Pro lepší představu, jak problém zhruba vypadal, jsem si udělal jednoduchý projekt a vytvořil testovací obsah, na kterém je problém patrný. Tvoří jej několikrát opakované logo Blogger služby, jednotlivá loga jsou oddělená mezerou - a celý obsah je na jedné řádce (shodně je nastaven i CK editor). Takto vytvořený obsah je uložen v souboru přidaném do projektu a nastaveném jako Embedded resource:
<p><img src="http://upload.wikimedia.org/wikipedia/commons/4/43/Social_icons-blogger-22x22.png" /> <img src="http://upload.wikimedia.org/wikipedia/commons/4/43/Social_icons-blogger-22x22.png" /> <img src="http://upload.wikimedia.org/wikipedia/commons/4/43/Social_icons-blogger-22x22.png" /> <img src="http://upload.wikimedia.org/wikipedia/commons/4/43/Social_icons-blogger-22x22.png" /> <img src="http://upload.wikimedia.org/wikipedia/commons/4/43/Social_icons-blogger-22x22.png" /> <img src="http://upload.wikimedia.org/wikipedia/commons/4/43/Social_icons-blogger-22x22.png" /> <img src="http://upload.wikimedia.org/wikipedia/commons/4/43/Social_icons-blogger-22x22.png" /> <img src="http://upload.wikimedia.org/wikipedia/commons/4/43/Social_icons-blogger-22x22.png" /> <img src="http://upload.wikimedia.org/wikipedia/commons/4/43/Social_icons-blogger-22x22.png" /> <img src="http://upload.wikimedia.org/wikipedia/commons/4/43/Social_icons-blogger-22x22.png" /> <img src="http://upload.wikimedia.org/wikipedia/commons/4/43/Social_icons-blogger-22x22.png" /> <img src="http://upload.wikimedia.org/wikipedia/commons/4/43/Social_icons-blogger-22x22.png" /> </p>
Pro odeslání emailu jsem použil SMTP server od GMail, tady je kód - pro odeslání je nutné samozřejmě použít platnou emailovou adresu a heslo (své údaje jsem odstranil). Email byl odeslán na dva účty, jeden na AOL a druhý na Yahoo:
const string SmtpServer = "smtp.gmail.com";
const int SmtpPort = 587;
const string FromAddress = "...@gmail.com";
const string SmtpPassword = "<vaseheslo>";
static readonly IEnumerable<string> ToAddresses = new string[] { "....@yahoo.com", "...@aol.com" };
static void Main(string[] args)
{
var content = GetResourceString("EmailTest.HtmlEmailContent.html");
SendEmail(content, "Blogger email");
}
static void SendEmail(string content, string subject)
{
using (MailMessage mail = new MailMessage())
{
mail.From = new MailAddress(FromAddress);
foreach (var address in ToAddresses)
mail.To.Add(address);
mail.IsBodyHtml = true;
mail.Body = content;
mail.BodyTransferEncoding = TransferEncoding.SevenBit;
mail.Subject = subject + " encoded as " + mail.BodyTransferEncoding.ToString();
using (var client = new SmtpClient(SmtpServer, SmtpPort))
{
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential(FromAddress, SmtpPassword);
client.EnableSsl = true;
client.Send(mail);
}
}
}
static string GetResourceString(string name)
{
using (var s = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
{
using (var reader = new StreamReader(s))
{
return reader.ReadToEnd();
}
}
}
const int SmtpPort = 587;
const string FromAddress = "...@gmail.com";
const string SmtpPassword = "<vaseheslo>";
static readonly IEnumerable<string> ToAddresses = new string[] { "....@yahoo.com", "...@aol.com" };
static void Main(string[] args)
{
var content = GetResourceString("EmailTest.HtmlEmailContent.html");
SendEmail(content, "Blogger email");
}
static void SendEmail(string content, string subject)
{
using (MailMessage mail = new MailMessage())
{
mail.From = new MailAddress(FromAddress);
foreach (var address in ToAddresses)
mail.To.Add(address);
mail.IsBodyHtml = true;
mail.Body = content;
mail.BodyTransferEncoding = TransferEncoding.SevenBit;
mail.Subject = subject + " encoded as " + mail.BodyTransferEncoding.ToString();
using (var client = new SmtpClient(SmtpServer, SmtpPort))
{
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential(FromAddress, SmtpPassword);
client.EnableSsl = true;
client.Send(mail);
}
}
}
static string GetResourceString(string name)
{
using (var s = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
{
using (var reader = new StreamReader(s))
{
return reader.ReadToEnd();
}
}
}
A tady je výsledek pro Yahoo - ten vypadá dobře:
Ale pro AOL je patrné, že je něco špatně:
Jeden z obrázků není zobrazen. Při kontrole HMTL kódu přes Developer Tools v prohlížeči Chrome (F12) je jasné, že je to díky mezeře/konci řádku v HMTL kódu:
A rozuzlení?
Emailový server byl špatně nakonfigurován a špatně formátoval odchozí emaily (což je v mém kódu nahoře simulováno nastavením na SevenBits). Nějaké další povídaní je i na http://sourceforge.net/p/dotnetopenmail/discussion/441285/thread/0a10e2c7/. Chyba se projevila pouze v případě, že na řádce bylo více jak 1000 znaků - dříve použivaný editor formátoval HTML na více řádků - zkrátka co HTML tag, to řádek a tak délka řádku nikdy nepřesáhla 1000 znaků a chyba se tak neprojevila.
Nový editor (CK editor) je nastaven na bez-řádkové formátování HTML a chyba se tak projevila - i když ne u všech příjemců - většina emailových klientů opravuje podobné chyby automaticky a tak jejich uživatelé, tedy příjemci emailů, nic nepoznají - což ovšem nebyl případ AOL.
Pokud se v kódu nahoře změní kódování, tj, z
mail.BodyTransferEncoding = TransferEncoding.SevenBit;
na
mail.BodyTransferEncoding = TransferEncoding.Unknown;
tak email již dorazí v pořádku:
Žádné komentáře:
Okomentovat