Sending email from any SMTP server from ASP.NET CORE application is pretty easy, but the flow of command is slight different in core environment.
Gmail SMTP server address is smtp.gmail.com
. It requires implicit SSL or explicit SSL (TLS) connection, and you should use your Gmail email address as the user name for ESMTP authentication.
So basically we will read email smtp address, port, username and password from appsettings.json, then will inject these config to email service class, in the end we will inject email service class to controller and consumer email send operation.
Step 1: Define email specific information in appsettings.json
{ "ConnectionStrings": { "DefaultConnection": "" }, "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information" } }, "EmailSettings": { "PrimaryDomain": "smtp.gmail.com", "PrimaryPort": "587", "SecondayDomain": "smtp.live.com", "SecondaryPort": "587", "UsernameEmail": "emailId@gmail.com", "UsernamePassword": "emailPassword", "FromEmail": "fromEmail", "ToEmail": "toEmail", "CcEmail": "ccEmail" } }
SmtpServer: The name of the server that will be used to send the emails.
SmtpPort: The port, which the server will use to send SMTP transactions (emails).
EnableSsl: True, if the server should use SSL (Secure Socket Layer) encryption.
Smtp Server Address and Port #
Server Name | SMTP Address | Port | SSL |
Yahoo! | smtp.mail.yahoo.com | 587 | Yes |
GMail | smtp.gmail.com | 587 | Yes |
Hotmail | smtp.live.com | 587 | Yes |
Step 2: Create a class to encapsulate EmailSettings properties from appsettings.json
public class EmailSettings { public String PrimaryDomain { get; set; } public int PrimaryPort { get; set; } public String SecondayDomain { get; set; } public int SecondaryPort { get; set; } public String UsernameEmail { get; set; } public String UsernamePassword { get; set; } public String FromEmail { get; set; } public String ToEmail { get; set; } public String CcEmail { get; set; } }
Step 3: Register class in startup.cs for DI purposes
services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
Step 4: Create an Email sender interface
public interface IEmailSender { Task SendEmailAsync(string email, string subject, string message); }
Step 5: Create a message service class which will implement this interface
Inject EmailSettings class in message service using options pattern, so that email configuration defined in appsettings.json is available in this service.
We will use SmtpClient class to allow applications to send e-mail by using the Simple Mail Transfer Protocol (SMTP).
public class AuthMessageSender : IEmailSender, ISmsSender { public AuthMessageSender(IOptions<EmailSettings> emailSettings) { _emailSettings = emailSettings.Value; } public EmailSettings _emailSettings { get; } public Task SendEmailAsync(string email, string subject, string message) { Execute (email, subject, message).Wait(); return Task.FromResult(0); } public async Task Execute(string email, string subject, string message) { try { string toEmail = string.IsNullOrEmpty(email) ? _emailSettings.ToEmail : email; MailMessage mail = new MailMessage() { From = new MailAddress(_emailSettings.UsernameEmail, "Muhammad Hassan Tariq") }; mail.To.Add(new MailAddress(toEmail)); mail.CC.Add(new MailAddress(_emailSettings.CcEmail)); mail.Subject = "Personal Management System - " + subject; mail.Body = message; mail.IsBodyHtml = true; mail.Priority = MailPriority.High; using (SmtpClient smtp = new SmtpClient(_emailSettings.SecondayDomain, _emailSettings.SecondaryPort)) { smtp.Credentials = new NetworkCredential(_emailSettings.UsernameEmail, _emailSettings.UsernamePassword); smtp.EnableSsl = true; await smtp.SendMailAsync(mail); } } catch(Exception ex) { //do something here } } }
*exception handling is left for you to implement
- You can attach one or several files:
mail.Attachments.Add(new Attachment(Server.MapPath("~/myimage.jpg")));
- You can send to more than one person at the same time
mail.To.Add("test@email.com"); mail.To.Add("test2@email.com");
- You can set a name for the sender
mail.From = new MailAddress("test@email.com", "Hello");
- You can send HTML e-mails, instead of the default plaintext mails
mail.IsBodyHtml = true; mail.Body = "Testing <b>123!</b>";
- You can use the CC and BCC fields
mail.CC.Add("test@email.com"); mail.Bcc.Add("test2@email.com");
- You can set the priority of an e-mail
mail.Priority = MailPriority.High;
Step 6: Register email sender service in startup.cs, so that it can be injected in controllers
services.AddTransient<IEmailSender, AuthMessageSender>();
Step 7: Controller code (consumer)
Inject email sender service in controller constructor and then invoke SendEmailAsync method of it
public class TestController : Controller { private readonly IEmailSender _emailSender; public AccountController(IEmailSender emailSender) { _emailSender = emailSender; } public async Task TestAction() { await _emailSender.SendEmailAsync("test@gmail.com", "subject", $"Enter email body here"); } }
Note:
Google may block sign in attempts from some apps or devices that do not use modern security standards. Since these apps and devices are easier to break into, blocking them helps keep your account safer.
Please make sure, in Gmail settings of your account, enable access for less secure apps to avoid below error:
The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required?