Altairis Mail Toolkit: mailování z webových aplikací snadno a korektně

Poslat e-mail z .NET aplikace není žádná velká věda. Stačí zavolat System.Net.Mail.SmtpMail.Send. Ale posílat maily způsobem korektním a dlouhodobě udržitelným, to je větší oříšek. Zveřejnil jsem proto open source knihovnu, která řeší obvyklé problémy s tím spojené.

Dobrý systém pro rozesílání zpráv by měl mít následující vlastnosti:

  • Umístění textů e-mailových zpráv mimo kód. Aby při změně formulace mailu nebylo nutné přepisovat backendový kód. Zároveň je nutné řešit doplňování údajů do relevantních šablon e-mailů.
  • Jednotný formát všech zpráv. Společné hlavičky/nožičky napomáhají snadné identifikaci zprávy a třeba i automatickému třídění.
  • Lokalizace do více jazyků. Problém komplikuje i to, že mnohdy chceme zprávu odeslat v jiném jazyce, než jaký je aktuálně používán. Např. akce způsobená uživatelem anglické verze se má oznámit uživateli jehož preferovaným jazykem je čeština.
  • Korektní nastavení hlaviček původce. Tedy From, Sender a Reply-To.
  • Rozesílání e-mailů na více adres současně. Ve většině případů je vhodné maily více příjemcům rozesílat tak, aby o sobě jednotliví příjemci nevědli, tj. aby každý měl vlastní kopii se svou adresou v hlavičce To.
  • Jednoduchost odeslání mailu z kódu, ideálně na jeden příkaz/řádek.
  • Centralizace konfigurace, aby změnu parametrů nebylo nutné provádět na mnoha místech najednou.

Kromě toho platí vše, co pro .NET aplikace všeobecně. Tedy maximální využití existujících standardů a infrastruktury, což zjednoduší zapojení do existujících struktur.

Altairis Mail Toolkit

Na základě zkušeností z předchozích projektů jsem vytvořil jednoduchou, ale celkem mocnou, komponentu jménem Altairis Mail Toolkit. Je k dispozici včetně zdrojového kódu a dokumentace na CodePlexu. Řeší všechny výše uvedené problémy, s použitím standardních .NETových technik.

Veškeré informace o formátu a textu mailů jsou uloženy ve standardních resource souborech. To elegantně řeší veškeré problémy spojené s lokalizací a umístěním textů zpráv mimo kód. Automaticky zajišťuje například možnost, aby text překládal neprogramátor jiným nástrojem, než Visual Studiem.

Samotné rozesílání mailů za nás řeší .NET Framework, stačí ho jenom správně nastavit. Obšírnější pojednání o významu hlaviček From, Reply-To a Sender jest nalézti v RFC 2822 a v poněkud zjednodušené formě jsem jej sepsal na CodePlexu (anglicky).

Konfigurace je řešena pomocí standardního .NET konfiguračního modelu, pomocí vlastní konfigurační sekce altairis.mailToolkit.

Vytváření šablon v resource souborech

Pro každou šablonu, tj. typ odesílaného mailu, je třeba vytvořit dva resource klíče. Jejich názvy začínají názvem šablony a následuje konfigurovatelný suffix – standardně Subject pro předmět zprávy a Body pro její text.

Šablona může obsahovat placeholdery v klasickém tvaru dle metody String.Format, tj {0} atd.

Kromě toho mohou existovat ještě další dva resource klíče, opět s konfigurovatelnými názvy, standardně _SubjectFormat a _BodyFormat (včetně úvodních podtržítek). Ty určují formát celé zprávy (předmětu a těla). Obsahují právě jeden placeholder {0}, kam se vloží celý zbytek textu.

Načítání resources z cizí assembly je pravděpodobně technicky nejkomplikovanější úkon, zbytek je technologicky triviální.

Odesílání mailů

Vlastní odeslání mailů z kódu realizují dvě metody statické třídy Altairis.MailToolkit.Mailer. Jmenují se SendTemplatedMessage a SendTemplatedMessages. Každá z nich má sbírku overloadů pro různé příležitosti, jejichž kompletní dokumentace je k dispozici online.

Pokud použijete overload se specifikací jazyka (CultureInfo), použije se příslušně lokalizovaná verze. Pokud je jazyk nastaven na null nebo se použije overload bez jeho určení, použije se aktuální UiCulture.

Komponentu Altairis Mail Toolkit si včetně zdrojového kódu a dokumentace můžete stáhnout na altairismailtoolkit.codeplex.com.

Titulek:
Text komentáře:
Vaše jméno:
Váš e-mail: (nebude zveřejněn)

WWW stránka:
Opište text z obrázku:
odpovědětodpovědět Gravatar

Resources

11.12.2010 10:32:5111.12.2010 10:32:51 TomášTomáš 217.117.208.---

Pro práci s resources se mi výborně osvědčil Zeta editor (http://www.zeta-resource-editor.com) Je zdarma a spoustu otročiny udělá za vás. Doporučuji!

odpovědětodpovědět Gravatar

Díky za užitečnou knihovnu!

12.12.2010 12:58:3912.12.2010 12:58:39 TomášTomáš 217.117.208.---

Právě jsem knihovnu naimplementoval - nebylo to složité a funguje skvěle. Michale, díky za skvělou věc!

odpovědětodpovědět Gravatar

Jak zjistit jméno vygenerovaného eml souboru?

12.12.2010 19:40:0212.12.2010 19:40:02 TomášTomáš 217.117.208.---

Metoda Send vytvoří soubor obsahující vlastní mailovou zprávu a tento soubor s příponou eml je odeslán dále (např. do složky specifikované pickupDirectoryLocation). Lze nějakým způsobem zjistit jméno tohoto vzniknuvšího souboru? Hodilo by se to v případě, když je potřeba např. vygenerovat hlavičkový soubor .hdr, který vyžaduje třeba SmarterMail apod.

odpovědětodpovědět Gravatar

RE: Jak zjistit jméno vygenerovaného eml souboru?

Obávám se, že nic takového vám standardní .NET Framework nenabídne. Metody třídy SmtpClient počítají buďto se síťovou komunikací přes SMTP a nebo s mail pickup service Microsoft SMTP Service. Nenabízí žádné extensibility points a podporu jiných serverů.

Asi nejčistší by bylo buďot posílat vše po síti přes SMTP a nebo si napsat udělátko, které bude hlídat pickup folder místo SMTPSVC a tamo umístěné soubory parsovat a přetvořit do formátu vhodného pro nějaký jiný server.

odpovědětodpovědět Gravatar

RE: Jak zjistit jméno vygenerovaného eml souboru?

12.12.2010 20:40:4612.12.2010 20:40:46 TomášTomáš 217.117.208.---

Je to tak, sám jsem teď po tom pátral. Jediné, co jsem našel, je tento odkaz níže:

http://www.codeproject.com/KB/IP/smtpcli…

Možná se toho dočkáme v pozdější verzi .NET FW. Varianta s např. službou, která by hlídala pickup folder mě taky napadla, ale obávím se, zda by se to negativně neprojevilo na výkonu systému - pokud se bude jednat o stovky nebo i tisíce mailů navíc s velikostí větší než malou, a takovou děsnou složku budu načítat a pak ještě parsovat eml soubor, tak to výkonu asi taky nepřidá.

Zaujal mě ale Tvůj nápad popisovaný v dřívějším článku o této problematice: mít puštěnou microsoftí SMTP službu na serveru a ty zprávy předhazovat jí. To by asi bylo nejschůdnější řešení. Přiznám se, že nemám moc rád řešení pomocí berliček, pokud to řešení příliš komplikuje.

odpovědětodpovědět Gravatar

ASP.NET: That assembly does not allow partially trusted callers

9.2.2011 16:12:459.2.2011 16:12:45 TomášTomáš ---.casablanca.cz

Pokud se setkáte s touto chybou (např. webhosting u Forpsi, ale obecně kdekoli), pak si lze pomoci drobnou úpravou souboru AssemblyInfo.cs ve zdrojích Altairis.MailToolkit:

doplňte do něj toto: [assembly: System.Security.AllowPartiallyTrustedCallers]

a vše zkompilujte. Vzniknuvší soubory .dll a pdb pak nakopírujte na příslušné místo do webu a mělo by to fungovat.

Vycházel jsem odsud:

http://kb.forpsi.com/article.php?id=582

Snad to někomu pomůže a pokud by se jednalo o nějaký potenciálně nebezpečný zásah (předpokládám, že snad ne), dejte prosím vědět.

Jinak komponenta funguje spolehlivě, ještě jednou díky!

odpovědětodpovědět Gravatar

RE: ASP.NET: That assembly does not allow partially trusted callers

Nojo, já tohle moc nemusím :-/ Nějak ta omezení nechápu.

Nicméně přidám to do další verze.

  • Altairis
  • Nemesis
  • Microsoft MVP
  • IIS
  • ASP.NET