Blog Dla Młodszych Programistów C#/.NET

23 listopada 2021
Tagi: C#/.NET
Często w swoich aplikacjach będziesz chciał zaimplementować funkcję wysyłki mailowej. W tym artykule pokaże Ci, jak może wyglądać taka przykładowa implementacja w C#. Napiszemy prostą aplikację konsolową do wysyłania maili z własnego konta gmail. Oczywiście taka implementacja będzie wyglądać tak samo w aplikacji webowej, mobilnej, czy desktopowej. Stworzymy takie uniwersalne rozwiązanie, które możesz użyć w dowolnej aplikacji.

Jak Wysyłać E-maile w C#? Prosta Implementacja Wysyłki Mailowej i Konfiguracja Konta Gmail


Projekt EmailSender


Przygotowałem wcześniej prostą aplikację konsolową o nazwie EmailSender.Client stworzoną w .NET 5.

namespace EmailSender.Client
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

Możemy w tym projekcie dodać implementacje wysyłki maili, ale dużo lepszym rozwiązaniem będzie stworzenie tej logiki w nowym projekcie, którego będziemy mogli później przenosić i używać w innych naszych projektach.

Także dodam teraz nowy projekt Class Library w .NET 5 o nazwie EmailSender.

Następnie w nowym projekcie dodamy kod wysyłki mailowej w klasie Email.

using System.Net;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;

namespace EmailSender
{
    public class Email
    {
        private SmtpClient _smtp;
        private MailMessage _mail;

        private string _hostSmtp;
        private bool _enableSsl;
        private int _port;
        private string _senderEmail;
        private string _senderEmailPassword;
        private string _senderName;

        public Email(EmailParams emailParams)
        {
            _hostSmtp = emailParams.HostSmtp;
            _enableSsl = emailParams.EnableSsl;
            _port = emailParams.Port;
            _senderEmail = emailParams.SenderEmail;
            _senderEmailPassword = emailParams.SenderEmailPassword;
            _senderName = emailParams.SenderName;
        }

        public async Task Send(string subject, string body, string to)
        {
            _mail = new MailMessage();
            _mail.From = new MailAddress(_senderEmail, _senderName);
            _mail.To.Add(new MailAddress(to));
            _mail.IsBodyHtml = true;
            _mail.Subject = subject;
            _mail.BodyEncoding = Encoding.UTF8;
            _mail.SubjectEncoding = Encoding.UTF8;
            _mail.Body = body;

            _smtp = new SmtpClient
            {
                Host = _hostSmtp,
                EnableSsl = _enableSsl,
                Port = _port,
                DeliveryMethod = SmtpDeliveryMethod.Network,
                UseDefaultCredentials = false,
                Credentials = new NetworkCredential(_senderEmail, _senderEmailPassword)
            };

            _smtp.SendCompleted += OnSendCompleted;

            await _smtp.SendMailAsync(_mail);
        }

        private void OnSendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            _smtp.Dispose();
            _mail.Dispose();
        }
    }
}

Do konstruktora będziemy potrzebowali przekazywać parametry konfiguracyjne, dlatego pomocna będzie do tego klasa EmailParams.

namespace EmailSender
{
    public class EmailParams
    {
        public string HostSmtp { get; set; }
        public bool EnableSsl { get; set; }
        public int Port { get; set; }
        public string SenderEmail { get; set; }
        public string SenderEmailPassword { get; set; }
        public string SenderName { get; set; }
    }
}

Czyli tak może wyglądać cały kod wysyłki e-mail.

Mamy kilka wartości konfiguracyjnych:
  • HostSmtp – adres hosta SMTP,
  • EnableSsl – informacja, czy używamy SSL,
  • Port – port wysyłki email,
  • SenderEmail – email nadawcy,
  • SenderEmailPassword – hasło maila nadawcy,
  • SenderName – nazwa nadawca.
Te parametry moglibyśmy przekazywać osobno do konstruktora, ale dużo lepszym rozwiązaniem przy takiej ilości parametrów jest właśnie stworzenie oddzielnej klasy. Dzięki temu zostanie przekazany tylko 1 parametr i nasz kod będzie bardziej rozszerzalny.

W klasie Email mamy też 1 metodę Send, dzięki której maila będą wysyłane. Potrzebujemy do tego między innymi 1 instancji SmtpClient, a także 1 instancji MailMessage. Do naszej metody przesyłamy 3 parametry. Są to kolejno temat maila, treść maila i email adresata. Wewnątrz metody Send ustawiamy odpowiednie właściwości dla naszych obiektów. Na koniec za pomocą metody SendMailAsync wysyłamy asynchronicznie maila do wybranego adresata. Subskrybujemy także zdarzenie SendCompleted, dzięki czemu obiekty _smtp oraz _mail zostaną odpowiednio zwolnione po wysłanym mailu.

Super, tak może wyglądać implementacja i możemy spróbować wysłać w metodzie głównej main w aplikacji konsolowej. Wcześniej jednak pamiętaj, aby w projekcie Client dodać referencję do nowego projektu EmailSender.

namespace EmailSender.Client
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var emailReceiver = "kazimierz.szpin@modestprogrammer.pl";

            var email = new Email(new EmailParams
            {
                HostSmtp = "smtp.gmail.com",
                Port = 587,
                EnableSsl = true,
                SenderName = "Kazimierz Szpin",
                SenderEmail = "modestprogrammertest@gmail.com",
                SenderEmailPassword = ""
            });

            Console.WriteLine("Wysyłanie e-mail'a...");

            await email.Send(
                "E'mail testowy z aplikacji!", 
                "Wysłano z aplikacji EmailSender.Client!",
                emailReceiver);

            Console.WriteLine("Wysłano e-mail'a...");
        }
    }
}

Będziemy próbować wysłać maila z adresu email: "modestprogrammertest@gmail.com" na adres: "kazimierz.szpin@modestprogrammer.pl". Przed i po wysłaniu maila zostaną wyświetlone w konsoli odpowiednie komunikaty.

Konfiguracja konta gmail


Aby wysłać e-mail, potrzebujemy jeszcze 2 rzeczy. Po pierwsze konta gmail. Zakładam, że już masz takie konto. Jeżeli nie, to koniecznie załóż. Oczywiście, równie dobrze ten kod zadziała, gdy będziesz chciał wysyłać maile z innego serwera, ale ten przykład akurat będzie bazował na gmailu. Do innych dostawców będziesz musiał tylko dostosować te wartości z klasy EmailParams i również wszystko zadziała bez problemu. Także, jeżeli masz już konto gmail, to musisz go jeszcze odpowiednio skonfigurować. Także pokaże Ci teraz, jak to musisz zrobić w gmailu.

Przejdź, proszę najpierw do swojego konta gmail. Kliknij w ustawienia i następnie konto:

Konfiguracja wysyłki e-mail - Etap 1

Po lewej stronie wybierz zakładkę bezpieczeństwo:

Konfiguracja wysyłki e-mail - Etap 2

Weryfikacja dwuetapowa:

Konfiguracja wysyłki e-mail - Etap 3

Rozpocznij:

Konfiguracja wysyłki e-mail - Etap 4

Tutaj zostaniesz poproszony o ponowne logowanie:

Konfiguracja wysyłki e-mail - Etap 5

Jeżeli nie skonfigurowałeś jeszcze swojego telefonu, to tutaj możesz to zrobić. Po wpisaniu swojego numeru telefonu wybraniu SMS i kliknięciu dalej – dostaniesz SMSa na swój telefon.

Konfiguracja wysyłki e-mail - Etap 6

W kolejnym kroku będziesz musiał wpisać ten numer z SMSa do odpowiedniego pola:

Konfiguracja wysyłki e-mail - Etap 7

Następnie kliknij dalej i włącz.

Jeżeli wszystko się udało, to wróć do zakładki bezpieczeństwo.

Konfiguracja wysyłki e-mail - Etap 2

Tym razem kliknij w Hasła do aplikacji:

Konfiguracja wysyłki e-mail - Etap 8

Ponownie się zaloguj.

Kliknij w Wybierz aplikację i wybierz opcję Inna opcja (nazwa własna):

Konfiguracja wysyłki e-mail - Etap 9

Wpisz dowolną nazwę, np. emailsender i kliknij Wygeneruj:

Konfiguracja wysyłki e-mail - Etap 10

W tym miejscu powinno się pojawić wygenerowane hasło na żółtym tle:

Konfiguracja wysyłki e-mail - Etap 11

Teraz wystarczy skopiować to hasło i przypisać do właściwości SenderEmailPassword w metodzie Main.

namespace EmailSender.Client
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var emailReceiver = "kazimierz.szpin@modestprogrammer.pl";

            var email = new Email(new EmailParams
            {
                HostSmtp = "smtp.gmail.com",
                Port = 587,
                EnableSsl = true,
                SenderName = "Kazimierz Szpin",
                SenderEmail = "modestprogrammertest@gmail.com",
                SenderEmailPassword = "muxpvgxitanxzswd"
            });

            Console.WriteLine("Wysyłanie e-mail'a...");

            await email.Send(
                "E'mail testowy z aplikacji!", 
                "Wysłano z aplikacji EmailSender.Client!",
                emailReceiver);

            Console.WriteLine("Wysłano e-mail'a...");
        }
    }
}

Jeżeli wszystko masz prawidłowo, to po uruchomieniu aplikacji powinien zostać wysłany nowy adres e-mail.


PODSUMOWANIE


Jak widzisz, implementacja wysyłki mailowej nie była skomplikowana. Stworzyliśmy całą wysyłkę w osobnej bibliotece (dll), dzięki czemu możemy ją używać również w innym naszych projektach. Tak jak Ci wspomniałem, w naszym przypadku wysyłamy maile z gmaila, ale ten kod również zadziała u innych dostawców.

To wszystko na dzisiaj, do zobaczenia w kolejnym artykule.

Poprzedni artykuł - FluentAssertions – Płynne Assercje w Testach Jednostkowych.
Następny artykuł - Czym Jest Programowanie? 10 Minutowe Wprowadzenie Dla Osób Nietechnicznych.
Autor artykułu:
Kazimierz Szpin
Kazimierz Szpin
Programista C#/.NET. Specjalizuje się w ASP.NET Core, ASP.NET MVC, ASP.NET Web API, WPF oraz Windows Forms.
Autor bloga ModestProgrammer.pl
Dodaj komentarz
© Copyright 2021 modestprogrammer.pl. Wszelkie prawa zastrzeżone. Polityka prywatności. Design by Kazimierz Szpin