Many times new developers stumble upon a very simple task, “sending emails” over the .NET framework. Well, I am not going to cover any specific language here (C# or VB.NET, Visual C++ you're also included), I will talk generally about the .NET framework and the assemblies exposed by the .NET framework for sending the emails, using your own SMTP server's settings, such as username/word combination, port number and (most especially) the hostname for your SMTP server.
Background
Emails stand for electronic mail and they are widely used on a regular basis for communication. You can send an email for sharing text data or you can send your albums over emails easily. Email has been a part of internet entertainment for a great time and people use a variety of email clients, some love online clients for example Gmail, Yahoo! and so on and some prefer an offline version of their email clients that use an internet connection to download the emails from a server, such as Thunderbird, Outlook and so on.
But the fact is that all of them use the same protocol for transferring emails over the internet network. In this article, I will talk about sending emails over the network, downloading the emails is a totally separate topic and would have a separate protocol working in the back end to download the emails from the server.
Sending the emails
Emails are sent using the SMTP protocol, over the internet. It is similar to the Hypertext protocol (not in the manner of communication, but in a way that is a protocol for communication). For more on SMTP, you can find yourself glad to read the Wikipedia page, I am not going in-depth of the protocol here, instead, I will just elaborate on the methods to send the emails over the .NET framework.
What does the .NET framework offer?
The .NET Framework (who is oblivious to that?) has many cool assemblies for us to work with, using our favorite languages, from C# to C++ and the assemblies in the .NET framework allow us to focus on the quality of the application and the logic, leaving the rest of the low-level coding to the framework itself, including and most especially the garbage collection like stuff and memory management.
.NET framework has a namespace, known as System.Net. This namespace is responsible for the network communication for the .NET applications. But we will be more concerned about the System.Net.Mail namespace, for working with the mail protocol that exposes the SmtpClient,MailMessage classes for us to easily just our data to the objects and send the email using the .NET framework.
Creating the module for sending email
Since the .NET framework exposes many frameworks to create your applications over, starting from something as basic as a Console application, to as much user-friendly as Windows Presentation Foundation. The interesting thing is that in the .NET framework, the same code can be used on the back-end of a Console app and the WPF application. So, the code that would be used to send the email in a Console application is just the same as you would be using for the WPF application. That is why I am not going to specify any framework, instead, I will use a Console application for our project, to be simpler to be understood and to focus more on the code instead. You can (in your own IDE) create any kind of application you want, from Windows Forms to WPF to a web application (using ASP.NET).
Once your application has been created, you can create a simple module (function; not to be confused with the VB.NET's Module). Inside that, you can write the following code, don't worry I will explain the code in the future section of the article.
// You should use a using statement
using (SmtpClient client = new SmtpClient("<smtp-server-address>", 25))
{
// Configure the client
client.EnableSsl = true;
client.Credentials = new NetworkCredential("<username>", "<word>");
// client.UseDefaultCredentials = true;
// A client has been created, now you need to create a MailMessage object
MailMessage message = new MailMessage(
"[email protected]", // From field
"[email protected]", // Recipient field
"Hello", // Subject of the email message
"World!" // Email message body
);
// Send the message
client.Send(message);
/*
* Since I was using the Console app, that is why I am able to use the Console
* object, your framework would have different ones.
* There is actually no need for these following lines, you can ignore them
* if you want to. SMTP protocol would still send the email yours.
*/
// Print a notification message
Console.WriteLine("Email has been sent.");
// Just for the sake of pausing the application
Console.Read();
}
Voila, (if you added correct details in the preceding code) you would have your emails sent to the destination without any trouble, apart from an internet connection trouble. Now let us dissect the code into pieces and understand what happened, then I will mention a few problems that arise in programming and cause havoc for new developers in understanding the entire process including the errors that are raised due to problems in connections and so on.
Explanation of the preceding code
The first step in the code is the usage of the using statement. In the .NET framework, you stumble upon various objects that use resources that need to be disposed of properly, or at least closed. For example, when a file is created it is required to call the Close() function before any other process can use that file, similarly, some processes require that you can a Dispose() function on them, to release all the resources. But you can use a using statement, to let the .NET framework take care of all of the objects that need such functions to be called themselves. For example, in the following code.
using (SmtpClient client = new SmtpClient())
{
// code here
}
Is better than
SmtpClient client = new SmtpClient();
// code here..
client.Dispose();
Due to many specific factors, that I am not going to talk about here. That leaves the discussion about the using statement, you will find a few deeper details about using statements on MSDN documentation.
Next comes the SmtpClient object. The SmtpClient creates an object that establishes the connection between your machine and the SMTP server you're using. SmtpClient requires you to set up a few things in it.
- The hostname is the name of your SMTP server's address in string format.
- The Port that you will be using to connect, default is 25 (TCP port).
- Most of the connections require that you set the SSL active. You can see that happening in our code too.
- Credentials are required before you can use a service, most of the servers (Gmail, Outlook, and so on) require that you send a username/word combination to send email from your account using the SMTP protocol. That is why in most cases default credentials forward the developers into errors. We use a NetworkCredential object (from System.Net namespace) to our username/word to the server.
Since SmtpClient is disposable we're using it inside a using statement. We're about to send an email, and for that, we create an object called MailMessage and our data to it. MailMessage object can set the From, To, Subject, and Body fields of an email message and then can be sent. You can see in our example, that we're using the constructor to create the MailMessage object that would hold the data for our From, To, Subject, and Body fields.
Finally, we're sending the email using the Send() function. The interesting thing is, in a GUI framework such as WPF or Windows Forms, we should be using SendAsync for the sake of asynchrony in our application that would help us to create a fluid GUI for our application, otherwise, the application would stay stuck until the email has been sent and the control continues from this line of code. To learn more about asynchronous programming, please move to the MSDN link and learn more from there, they've got great content for beginners like you.
A few errors in the programming
Generally, there are always errors that developers miss and then they become about “Where did I miss it?”. Similarly, in sending the email and establishing a secure connection, there are usually many problems, some are syntax, some are logical, but I would talk about the connection errors that might be raised. I tried to raise some exceptions myself to share them with you here, for you to understand when these exceptions might cause problems for your environment.
Usually, the exceptions in the connection are raised only at the Send, or SendAsync method when the SmtpClient is not able to send your email successfully. It can be due to a connection problem, authentication problem, or any other problem.
Problems with SMTP hostname
A general problem can be the hostname that you're in to the client to connect to, it must be correct and without the “http://“. You might stumble upon such a problem.
Hostname could not be resolved, because it has “http://” in it. Just the smtp.gmail.com, if you're using Gmail as your SMTP server. Otherwise, you should contact the SMTP developers for their SMTP hostname.
This would be resolved, by making sure that the hostname is correct. Every SMTP provider has its own settings for its server. Make sure you're using the correct ones. This is the first problem you would stumble upon if you're going to get any error. Failure to send mail can also be raised if the Firewall is blocking the network.
Another problem with the SmtpClient is, if you're not using the correct port number, then the connection might not be established and the worst thing is that there won't be any exception raised. For example, use port number 295. The command would continue to execute without any success message or exception. Make sure you're using the correct port number, otherwise, use the default TCP port number; 25. Port number 25 always works for me.
Errors authenticating the user
Whereas servers require the correct authentication, it is necessary that you the correct and required authentication details to the server. The first stage is to enable the SSL over your connection. Usually, servers close the connection if the connection isn't over SSL. Recall the code in this article and see the enable SSL command as in the following.
client.EnableSsl = true;
After this, you should ensure that you're using the correct combination of your username and word. If they're incorrect, the server is free to close the connection. The following exception is raised if any of such (authentication) problems occur in your application.
The server requires an SSL connection or the correct username/word combination. Make sure you're not wrong in both of these scenarios.
Once these problems are resolved (and other problems don't arise) your email will be sent and you will see a success message in your application. Mine showed me the following.
Email successfully sent! Success message in the Console application.
Points of Interest
In the .NET Framework, you can use the System.Net and its namespace to work with the network. For mailing, you use the System.Net.Mail namespace. System.Net.Mail exposes a SmtpClient object, that uses a hostname and a port to connect to the SMTP server for sending the emails. Some of the servers require an SSL connection and credentials (username/word combination).
MailMessage is the object you would use to send the email, you can fill this object with the From, To, Subject, and Body fields of your email message. SmtpClient would send this object, you can use Send or SendAsync methods to send an email, depending on your framework and the methods that you would use to send the email.
Exceptions are raised in SmtpClient when the code reaches the Send (or SendAsync) function. That is because connection problems occur at this stage, the server tells the .NET framework for the errors in sending the email, and the exception is raised. Usually, the exceptions are raised for the following factors.
- The username/word is incorrect.
- SSL is not enabled.
- The hostname is not correct, so the SmtpClient was not able to establish the connection at all.
- If the port number is incorrect, there is no error message at all. This is a tricky part for every developer. You can minimize this problem by using 25 (the default TCP port).
SmtpClient exposes the Dispose() function, which is why it is better to use the SmtpClient object in a using statement, not just as a simple (and ordinary) object to call dispose of over later. Using a statement lets you leave the release of the resources to the .NET framework itself.
For those looking for a VB.NET code, you can use the Telerik converter to convert your C# code to VB.NET code (or vice versa).
.NET allows you to use the same code over various frameworks and platforms that run over . NET. Such as WPF, Console app, and ASP.NET web applications. That is why you can use this code above in nearly all of your applications, no matter the software apps, web apps, or whatever client application you're creating until it runs over the .NET framework. Because these assemblies are present in .NET, not in the language itself.