Introduction
When you search for this on google you will find one hundred million results that all pretty much say exactly the same thing. The problem is none of them are from a developer’s perspective (from what I can tell) therefore none of the articles explained what was needed to make it work with the C# System.Net.Mail.SmtpClient class. After a lot of trial and error with frustration sprinkled in, I figured it out. Unfortunately, I am not 100% sure what combination of things I did made everything work.
Setup your Google account security first
Nothing works unless you have setup your account security correctly. There are some older articles that indicate a flag in your account about enabling “Unsafe applications” – skip this and enable two-factor authentication (2FA) on your account instead. The reason you need 2FA is so you can create an application password instead.
- Go to https://myaccount.google.com/
- On the left-hand side of the page locate the “Security” link.
- Under the “Signing in to Google” section go through the motions of enabling 2FA – I won’t explain that here. When 2FA is enabled go on to the next step.
- After 2FA is enabled you will see “App passwords” shows up in the “Signing in to Google” section under 2FA.
- Fill out the form – really it doesn’t matter how you do this but for the sake of argument:
- For the “Select app” drop down select “Other”
- Enter whatever meaningful name you want
- For the “Select device” drop down select “Windows Computer”
- Click the “GENERATE” button
- Copy the password
- Note: Even though it presents with spaces, it won’t have spaces after you copy it.
- Keep your password handy for the next part
Gmail settings
In order for this to work correctly you now need to enable POP and IMAP access. I will be perfectly honest; this is where I got confused I enabled both because I was annoyed at this point with not knowing why none of this was working.
- Go to https://mail.google.com and access your settings
- Click on the “Forwarding and POP/IMAP” section
- Enable POP
- Fill this section out however you want as long as it is enabled
- Enable IMAP
- Fill this section out however you want as long as it is enabled
- Enable POP
SMTP settings
Reminder, these instructions are for sending an email using Gmail’s SMTP settings specifically for use with the System.Net.Mail.SmtpClient.
Property | Value |
---|---|
DeliveryMethod | SmtpDeliveryMethod.Network |
Host | smtp.gmail.com |
Port | 587 |
EnableSsl | true |
UseDefaultCredentials | true |
Credentials | Look below for more details |
Credentials
I could not find a straight forward answer on what the user name is supposed to be when using app passwords. It is safe to say it is the same username of the account and I have tested this, it works just fine. I just wanted written instructions that say this clearly. It’s only hinted at.
For the “Credentials” property you need to use a “System.Net.NetworkCredential” object and populate using the second constructor which takes two strings:
Argument | Value description |
---|---|
userName | Your gmail account email address in the form: “[email protected]” |
password | The application password generated up top |
Code example
I use LinqPad for doing quick modeling of things. This was created using LinqPad and I have provided the raw format of that file so namespaces are included:
<Query Kind="Program">
<Namespace>System.Net.Mail</Namespace>
<Namespace>System.Net</Namespace>
</Query>
void Main()
{
SendViaGmail(new Email());
}
public void SendViaGmail(Email email)
{
using (var client = new SmtpClient())
{
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Host = "smtp.gmail.com";
client.Port = 587; //SSL 465, TLS: 587 - TLS is what worked
client.EnableSsl = true;
client.UseDefaultCredentials = true;
client.Credentials = new NetworkCredential("[email protected]", "TheAppPasswordYouGenerated");
using (var mail = new MailMessage(email.From, email.To))
{
mail.Subject = email.Subject;
mail.Body = email.Message;
mail.IsBodyHtml = true;
client.Send(mail);
Console.WriteLine($"{email.To}, {email.Subject}, {mail.Body}");
}
}
}
public class Email
{
public const string StockSubject = "This is a test email";
public string From { get; set; } = @"[email protected]";
public string To { get; set; } = @"[email protected]";
public string Subject { get; set; } = StockSubject;
public string Message { get; set; } = @"<html><span>This is a test heading</span></html>";
}
The thing that really got me screwed up for a while was trying to figure out which port to use. I kept trying to use SSL 465 when it turned out to be TLS 587 that worked. I’m still confused as to why SSL 465 didn’t work.