Posílání e-mailů v ASP.NET Core

23.5.2024 Editováno: 23.6.2024 Kategorie: Technologie

Po delší době jsem opět programoval ve frameworku .NET pomocí jazyka C#. Již nějaký čas uvažuji o tom, jakým způsobem vyřešit posílání e-mailů při použití této technologie. U PHP stačí použít funkci mail() a je hotovo. V C# to však tak jednoduché není. Ale zase vám to nabízí daleko větší možnosti customizace.

Jelikož je pro mě programování spíše koníček a nevěnuji se mu každý den, potřeboval jsem si osvěžit znalosti. V mnoha věcech jsem se tedy inspiroval v článku How to Send an Email in ASP.NET Core - Code Maze (code-maze.com). Rozhodně doporučuji si přečíst jak článek, tak shlédnout video, stojí to za to.

 

Na vyzkoušení celého principu jsem si vytvořil jednoduchou aplikaci jménem WolfsEmails na designovém vzoru ASP.NET Core MVC. V aplikaci jsem vytvořil .NET class library EmailServices, která obsahuje potřebné třídy a rozhraní pro vytvoření a konfiguraci samotné emailové zprávy. Samozřejmě jsem vytvořil referenci z hlavního řešení WolfsEmail na EmailServices.

Řešení obsažená v projektu WolfsEmails

Následně bylo potřeba zaregistrovat třídu EmailConfiguration v Program.cs, aby si následně mohla tahat data ze souboru appsetings.json, kde jsem vytvořil samostatný oddíl EmailConfiguration. Jen pro upřesnění zmíním, že pomocí tohoto řešení se emaily posílají s využitím nějakého externího poštovního serveru. Nastavení a zadávání údajů je zde tedy podobné jako u emailového klienta.

Ukázka souboru apssetings.json

Další zajímavé věci se odehrávají v aplikační vrstvě. Zde jsem využil výchozí HomeController, protože samotný formulář se nachází na index.cshtml. Celá hlavní logika aplikaci je integrována do postové akce sendEmail. V článku, na nějž odkazuji výše autor rozebírá možnost asynchronního zpracování požadavků. Celé toto téma jde trošku mimo mě. O výcevláknových aplikacích jsem kdysi něco četl ale v praxi jsem je nikdy nepoužíval. Proto jsem do toho ani v tomto případě nepouštěl.

Postová akce sendEmail

Povšimněte si zde třídy ControlQuestions. To je můj vlastní vynález. Všichni dobře známe ověřování reCaptcha. Je to dobrý a ověřený systém ale chtěl jsem něco trochu více originálního. Ale co si budeme povídat, dnešní neuronové sítě si s tím hravě poradí. Jde spíše o to, že jsem vymyslel vlastní systém. Celé je to založené na kontrolních otázkách na které musí návštěvník slovně odpovědět. Tedy úkol, který by ještě před pěti lety zamotal bity kdejakému škodlivému robotovi.

 Třída ControllQuestions

Základem celé třídy ControlQuestions jsou dvě pole. Jedno pro otázky a druhé pro odpovědi. Pak už je zde jen proměnná random odvozená od třídy Random(). Ta slouží pro generování náhodného indexu v rozsahu délky pole. Třída obsahuje dvě veřejné metody pro práci s těmito hodnotami. Metoda GenerateIndex() nám vygeneruje index, který následně vložíme jako jeden z parametrů do metody CompareInputs(). Druhým parametrem je vstup od uživatele. Pak už je to jednoduché. Musíme ale uvažovat o logice, která se implementuje do pohledu, který provádí samotnou interakci s uživatelem. Jinak by to nefungovalo. To znamená, že poté co uživatel odpoví na otázku, která byla vybrána dle vygenerovaného indexu se jak odpověď tak index přenese v postu do controlleru. Zde se zavolá zmíněná metoda CompareInputs(). Ta nám dle indexu vybere správnou odpověď z předpřipraveného pole Answers a porovná ji s uživatelovou odpovědí. Pak nám vrátí logickou hodnotu true či false. Což se skvěle hodí právě do podmínek, kde se rozhodne, jestli bude akce pokračovat ke zdárnému výsledku, nebo vrátí nějakou chybovou hlášku.

Teď jsem trochu odbočil od té hlavní logiky celé aplikace. Takže zpět k posílání e-mailů. S vybudováním celé logiky nám pomůže knihovna MailKit. Samotné poslání zprávy budeme volat veřejnou metodou SendEmail(), které předáme jako parametr instanci třídy Message. Tato metoda potřebuje dvě privátní metody. Metoda CreateEmailMessage() nám sestaví samotnou zprávu a vrátí nám ji jako instanci třídy MimeMessage(). Druhá metoda Send() si tuto instanci přebere jako parametr a pomocí třídy SmtpClient() se postará o samotnou komunikaci s poštovním serverem a zprávu odešle. Akce sendEmail() následně uživatele přesměruje zpět na hlavní stránku.

Jedním z dalších zajímavých prvků je zpráva pro uživatele. Podobně jako u kontrolní otázky jsem zde použil kód, který jsem vytvořil již kdysi dávno pro své projekty napsané v PHP. Akorát, že v .NET je to daleko zajímavější. K samotnému ukládání zprávy se v ASP.NET Core nejlépe používá kolekce TempData, která data následně sama smaže. Při řešení tohoto problému jsem si nejvíce vyhrál se samotnou tvorbou html kódu pomocí C#.

 

Metoda RenderMessageBox

V .NET k podobným účelům slouží třídy HtmlContentBuilder() a TagBuilder(). S jejich pomocí velmi snadno postavíme klasický html kód s třídami i atributy. Chvíli jsem přemýšlel nad velmi jednoduchou věcí, jak dostat jeden html tag dovnitř druhého. Zkrátka mít jeden div uvnitř druhého. Slouží k tomu vlastnost InnerHtml, pomocí níž jednoduše definujeme, jaký obsah, tedy třeba další tag má být uvnitř tohoto tagu. Takto si poskládáme pomocí metody v podstatě jakýkoliv html kód. Samotnou metodu následně zavoláme v pohledu _layout.

Pohled Layout

Jelikož nejsem příliš velkým fanouškem různých knihoven css stylů, napsal jsem si styly vlastní, včetně responzivity. Za zmínku asi nejvíce stojí zoom efekt u elementů textarea a input ve formuláři.

Náhled zoom efektu

Docílil jsem toho jednoduchou pseudotřídou focus. Pomocí ní nastavujeme, co se má s elementem stát, pokud do něj třeba klikneme. Zde jsem toho využil pro nastavení dvou vlastností. Tou první je transition, tedy zpoždění v délce 0.5s. To znamená, že se vlastnost, která následuje dále nenastaví ihned ale bude to trvat 0.5s. Jako další vlastnost je transform, kde nastavíme měřítko scale(1.2). Jen pro upřesnění, pokud nastavíme 1, velikost se nezmění ale zůstane stejná. Tím jsem velmi jednoduše shrnul základní funkčnost celé aplikace. Celý zdrojový kód je k dispozici na mém GitHub účtu: lonelyWolf-developer/WolfEmails (github.com). Přeji mnoho úspěchů s implementací tohoto nebo podobného řešení do vlastních projektů.