Most of the times new developers stumble upon a very simple task, “sending emails” over .NET framework. Well, I am not going to talk about any language here (C# or VB.NET, Visual C++ you’re also included), I am going to talk generally about the .NET framework and the assemblies exposed by .NET framework for sending the emails, using your own SMTP server’s settings, such as username/password combination, port number and (most specially) the hostname for your SMTP server.
Background
Emails stands for electronic mail, and they are widely used in regular basis for communication, you can send email for sharing text data or you can send your albums over emails easily. Email has been a part of the internet entertainment since a great time, and people use many different email clients, some love the online clients eg. Gmail, Yahoo! etc, and some prefer an offline version of their email clients which use the internet connection to download the emails from a server, such as Thunderbird, Outlook etc.
But the fact is that all of them use the same protocol for transferring the emails over internet network. In this blog post, I will talk about sending the emails over the network, downloading the emails is a totally seperate topic and would have a seperate protocol working on 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 way of communication, but in a way that is a protocol for communcation). 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 the methods to send the emails over the .NET framework.
What does .NET framework offer me?
.NET framework (who is oblivious to this one?) has a bunch of cool assemblies for us to work with, using our favourite 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 specially 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, which exposes the SmtpClient, MailMessage classes for us to easily just pass our data to the objects and send the email using .NET framework.
Creating the module for sending email
Since .NET framework exposes a lot of frameworks to create your applications over, starting from as basic as Console application, to as much user-friendly as Windows Presentation Foundation. Interesting thing is, that in .NET framework 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 am going to use a Console application for our project, for being 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 coming section of the blog post.
using (SmtpClient client = new SmtpClient("<smtp-server-address>", 25))
{
client.EnableSsl = true;
client.Credentials = new NetworkCredential("<username>", "<password>");
MailMessage message = new MailMessage(
"from@example.com",
"to@example.com",
"Hello",
"World!"
);
client.Send(message);
Console.WriteLine("Email has been sent.");
Console.Read();
}
Voila, (if you added correct details in the above code) you would have your emails sent to destination without any trouble; apart from Internet connection trouble. Now let us dissect the code into pieces and understand what happened, after that I will mention a few problems that arise in programming and cause a havoc for new developers in understanding the entire process, which includes the errors that are raised due to problems in connections and so on.
Explaination of the above code
First step in the code is the usage of the using
statement. In .NET framework, you stumble upon different objects that use resources, which need to be disposed off properly, or atleast closed. For example, while a file is created it is required to call the Close()
function, before any other process can use that file, similarly some processes requires 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 itself. For example, the following code,
using (SmtpClient client = new SmtpClient()) {
}
is better than,
SmtpClient client = new SmtpClient();
client.Dispose();
due to many particular factors, that I am not going to talk about here. That leaves the discussion about the using statement, you would find a few more deeper detail about using statements on MSDN documentations.
Next comes the SmtpClient
object, the SmtpClient
is used to create an object that would establish the connection between your machine and the SMTP server you’re using. SmtpClient
requires you to set up a few things in it.
- Host name, which is the name of your SMTP server’s address in string format.
- 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 etc) require that you send a username/password combination in order to send email from your account using the SMTP protocol. That is why in most of the cases default credentials forward the developers into errors. We use NetworkCredential object (from System.Net namespace) to pass our username/password to the server.
Since SmtpClient
is disposable, that is why we’re using it inside a using statement. We’re about to send an email, for that we create an object called MailMessage
, and we pass our data to it. MailMessage
object can set From, To, Subject and Body fields of an email message and then can be sent. You can see in our example, 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. Interesting thing is, in a GUI framework such as WPF or Win 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 woul stay stuck until the email has been sent and the control continues from this line of code. To learn more on asynchronous programming, please move to the MSDN link and learn more from there, they’ve got a great content for beginners like you.
A few errors in programming
Generally, there are always errors that developers miss and then tries to confuse himself for “Where did I miss it?”. Similarly, in sending the email and establishing a secure connection, there are usually a lot of problems, some are syntax, some are logically, 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 a 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 the connection problem, authentication problem or any other problem.
Problems with SMTP hostname
A general problem can be the hostname that you’re passing 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 is having “http://" in it. Just pass 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 setting 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 sending 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 establish and the worst thing is that there won’t be any exception raised. For example, use 295 port number. The command would continue to execute without any success message or exception. Make sure you’re using correct port number, otherwise use the default TCP port number; 25. For me, 25 port number works always.
Errors authenticating the user
While servers require the correct authentication, it is compulsary that you pass correct and required authentication details to the server. First stage is to enable the SSL over your connection. Mostly, servers close the connection if the connection isn’t over SSL. Recall the code in this blog post, and see the enable SSL command,
client.EnableSsl = true;
After this, you should make sure that you’re using the correct combination of your username and password. If they’re incorrect, server is free to close the connection. The following exception is raised if any of such (authentication) problem occurs in your application.
Server requires SSL connection, or correct username/password combination. Make sure you’re not wrong in both of these scenarios.
Once these problems are resolved, (and other problems don’t come out) your email would 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 .NET framework you can use the System.Net
and its namespace to work with network. For mailing, you use the System.Net.Mail
namespace. System.Net.Mail
exposes an SmtpClient
object, that uses a hostname and a port to connect to the SMTP server for sending the emails. Some of the servers require SSL connection, and credentials (username/password combination).
MailMessage
is the object you would use to send the email, you can fill this object with the From, To, Subject and Body field of your email message. SmtpClient
would send this object, you can use Send
or SendAsync
methods to send email, depending on your framework and the methods that you would use to send the email from.
Exceptions are raised in SmtpClient
, when the code reaches the Send (or SendAsync) function. That is because the connection problems occur at this stage, server tells the .NET framework for the errors in sending the email, and the exception is raised. Usually exceptions are raised due to following factors,
- Username/Password is incorrect.
- SSL is not enabled.
- 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. This can be minimized by using 25 (default TCP port).
SmtpClient exposes Dispose()
function, that 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 over later. Using a using statement lets you leave the releasing of the resources to the .NET framework itself.
For those, who are looking for a VB.NET code, you can use the Telerik converter to convert your C# code in VB.NET code (or vice versa).
.NET allows you to use the same code over different frameworks and platforms that run over .NET. Such as WPF, Console app, ASP.NET web applications. That is why, you can use this code above in almost all of your applications, no matter software apps, web apps or what-so-ever client application you’re creating until it runs over .NET framework. Because these assemblies are present in .NET, not in the language itself.