Poniższy artykuł pochodzi z serii Przygotowań do egzaminu 70-536.
Jak wysłać wiadomość
Po utworzeniu wiadomości, musimy wysłać ją przez serwer SMTP, który prześle wiadomość do odbiorcy. W .NET klasą, która reprezentuje serwer SMTP jest klasa SmtpClient. Aby wysłać wiadomość wywołujemy SmtpClient.Send. Najczęściej wysyłanie wiadomości jest tak proste jak w poniższym przykładzie(gdzie smtp.contoso.com jest nazwą lokalnego serwera SMTP):
1: MailMessage m = new MailMessage
2: ("jane@northrup.org",
3: "ben@northrup.org",
4: "Quarterly data report.",
5: "Hello, world.");
6: SmtpClient client = new SmtpClient("smtp.contoso.com");
7: client.Send(m);
Obsługiwanie wyjątków E-mail
Podczas wysyłania wiadomości, wiele rzeczy może pójść nie tak. Na przykład: serwer może nie być dostępny, serwer może odrzucić poświadczenia użytkownika itp. W każdym takim przypadku runtime rzuca wyjątkiem a my musimy tak przygotować naszą aplikację, żeby ten wyjątek złapała i obsłużyła.
Kiedy wysyłamy wiadomości, powinniśmy być zawsze przygotowani na złapanie wyjątku SmtpException.
Wiadomości często są odrzucane ponieważ np. nie można odnaleźć serwera smtp, serwer identyfikuje wiadomość jako spam itd.
Powinniśmy również obsługiwać wyjątek SmtpFailedRecipientException, który runtime rzuca jeśli serwer smtp odrzuca email odbiorcy.
Poniższa tabelka podsumowuje wyjątki, które mogą być rzucone podczas pracy z mailami:
| Sytuacja |
Wyjątek |
| Nie określono serwera hosta |
InvalidOperationException |
| Nazwa serwera hosta nie została znaleziona |
SmtpException z wewnętrznym WebException |
| Wysyłasz maila do odbiorcy na lokalnym serwerze ale odbiorca nie ma poczty |
SmtpFailedRecipientException |
| Niepoprawny user bądź są inne problemy z transmisją nieobjętych w innych wyjątkach |
SmtpException |
Jak konfigurować poświadczenia
Aby zredukować spam, wszystkie serwery smtp powinny odrzucać wiadomości od nieautoryzowanych użytkowników. Serwery smtp dostarczane przez dostawców usług internetowych zwykle określają, który użytkownik jest uprawniony na podstawie jego adresu IP.
Inne serwery smtp wymagają od użytkownika dostarczenia nazwy użytkownika oraz hasła. Aby użyć domyślnych poświadczeń sieciowych, ustaw SmtpClient.UseDefaultCredentials na true. Alternatywnie można ustawić SmtpClient.Credentials na CredentialCache.DefaultNetworkCredentials, jak na poniższym przykładzie:
1: SmtpClient client = new SmtpClient("smtp.contoso.com");
2: client.Credentials = CredentialCache.DefaultNetworkCredentials;
Aby określić nazwę użytkownika i hasło, musimy stworzyć instancję klasy System.Net.NetworkCredential i użyć jej do zdefiniowania SmtpClient.Credentials. Poniższy przykład pokazuje zaprogramowane na stałe poświadczenia:
1: SmtpClient client = new SmtpClient("smtp.contoso.com");
2: client.Credentials = new NetworkCredential("user", "password");
Jak skonfigurować SSL
Inną bardzo ważną właściwością związaną z bezpieczeństwem jest SmtpClient.EnableSsl. Kiedy ustawimy tę właściwość na true, runtime szyfruje połączenia SMTP używając SSL. Należy jednak pamiętać, że nie wszystkie serwery smtp wspierają SSL.
Jak wysyłać wiadomości asynchronicznie
Wysyłanie wiadomości e-mail często trwa mniej niż sekundę. Jednak często serwer smtp jest powolny lub w ogóle nie odpowiada. Wtedy nasza aplikacja czeka tyle ile określiliśmy w SmtpClient.Timeout. Choć aplikacja czeka wtedy na serwer smtp, użytkownik nie może robić nic w międzyczasie.
Na szczęście można wysyłać wiadomości asynchronicznie, czyli tak, żeby użytkownik nie musiał czekać aż e-mail zostanie wysłany. Możemy również dać użytkownikowi opcję anulowania wysyłania.
Aby wysyłać wiadomość asynchronicznie należy:
1. Stworzyć metodę SmtpClient.SendCompleted, która reaguje na zdarzenie. Metoda wymaga ustalenia czy transmisja się udała, nie udała bądź czy została anulowana.
2. Dodajemy obsługę zdarzenia SmtpClient.SendCompleted.
3. Wywołujemy SmptClient.SendAsync.
4. Jeśli chcesz udostępnić użytkownikowi anulowanie emaili, możesz to zrobić za pomocą metody SmtpClient.SendAsyncCancel.
Przykład:
1: static void sc_SendCompleted(object sender, AsyncCompletedEventArgs e)
2: {
3: if (e.Cancelled)
4: Console.WriteLine("Message cancelled");
5: else if (e.Error != null)
6: Console.WriteLine("Error: " + e.Error.ToString());
7: else
8: Console.WriteLine("Message sent");
9: }
Poniższy kod tworzy obiekt SmtpClient, dodaje obsługę zdarzenia, wywołuje asynchroniczne wysyłanie a następnie natychmiast to wysyłanie anuluje. Oczywiście, w prawdziwym programie powinniśmy poczekać aż użytkownik sam anuluje wysyłanie :). Zakładamy że obiekt MailMessage o nazwie mm już istnieje.
1: SmtpClient sc = new SmtpClient("server_name");
2: // Add the event handler
3: sc.SendCompleted += new SendCompletedEventHandler(sc_SendCompleted);
4: // Send the message asynchronously
5: sc.SendAsync(mm, null);
6: // Cancel the send
7: sc.SendAsyncCancel();
SmtpClient.SendAsync akceptuje dwa parametry: obiekt MailMessage do wysłania oraz jakiś drugi, który jest obiektem wyłącznie do własnego użytku.
To wszystko na dzisiaj i to wszystko z mojej strony w tej serii artykułów. W środę ukaże się ostatni artykuł z serii 70-536. Dzięki za uwagę i być może do “usłyszenia” w następnej serii.
Kolejny artykuł z serii to Formatowanie danych za pomocą mechanizmu globalizacji