- Gửi Mail trong .NET C#
- Gửi mail từ localhost SMTP
- Gửi mail dùng SMTP Server Google (gmail)
- Dùng MailKit gửi Mail trong ASP.NET với Gmail
Gửi Mail trong .Net Core
Thư viện .NET cung cấp lớp SmtpClient
cho phép bạn gửi Email thông qua giao
thức SMTP (Simple Mail Transfer Protocol), chức năng của SmtpClient là chuyển Email tới máy
chủ SMTP để máy chủ này thực hiện việc chuyển Email đến địa chỉ người nhận.
Khi đã có đối tượng SmtpClient thì thực hiện chuyển email bằng cách biên tập nội dung email
với đối tượng lớp MailMessage
sau đó gọi phương thức SendMailAsync
của SmtpClient
để chuyển.
Ví dụ phương thức tính sau để gửi email từ đối tượng SmtpClient đã có
using System; using System.Net; using System.Net.Mail; using System.Threading.Tasks; namespace MailUtils { public static class MailUtils { /// <summary> /// Gửi Email /// </summary> /// <param name="_from">Địa chỉ email gửi</param> /// <param name="_to">Địa chỉ email nhận</param> /// <param name="_subject">Chủ đề của email</param> /// <param name="_body">Nội dung (hỗ trợ HTML) của email</param> /// <param name="client">SmtpClient - kết nối smtp để chuyển thư</param> /// <returns>Task</returns> public static async Task<bool> SendMail(string _from, string _to, string _subject, string _body, SmtpClient client) { // Tạo nội dung Email MailMessage message = new MailMessage ( from: _from, to: _to, subject: _subject, body: _body ); message.BodyEncoding = System.Text.Encoding.UTF8; message.SubjectEncoding = System.Text.Encoding.UTF8; message.IsBodyHtml = true; message.ReplyToList.Add (new MailAddress (_from)); message.Sender = new MailAddress (_from); try { await client.SendMailAsync (message); return true; } catch (Exception ex) { Console.WriteLine (ex.Message); return false; } } } }
Lớp tĩnh trên cung cấp phương thức để bạn gửi mail khi đã có SmtpClient, gọi bằng cách:
await MailUtils.SendMail(_from, _to, _subject, _body, client);
Ví dụ:
await MailUtils.SendMail("myemail@domain.com", "yourmail@domain.com", "Gửi mail", "Nội dung Email", client);
Chú ý lời gọi SendMail trên là bất đồng bộ, nếu code gọi đồng bộ thì: MailUtils.SendMail(..).Wait();
Gửi Mail với Smtp Server Localhost
Nếu bạn có Server Smtp cài đặt cùng host của ứng dụng thì bạn có thể khởi tạo SmtpCLient sau đó sử dụng hàm SendMail ở trên để chuyển thư
Ví dụ, xây dựng phương thức tĩnh SendMailLocalSmtp
như sau:
namespace MailUtils { public static class MailUtils { // ... /// <summary> /// Gửi Email sử dụng máy chủ SMTP cài đặt localhost /// </summary> public static async Task<bool> SendMailLocalSmtp ( string _from, string _to, string _subject, string _body) { using (SmtpClient client = new SmtpClient ("localhost")) { return await SendMail(_from, _to, _subject, _body, client); } } } }
Ví dụ thực hiện gửi mail:
await MailUtils.MailUtils.SendMailLocalSmtp("sender@mail.com", "recevier@mail.com", "Chủ đề", "Nội dung email");
Nếu gọi đồng bộ thì:
MailUtils.MailUtils.SendMailLocalSmtp("sender@mail.com", "recevier@mail.com", "Chủ đề", "Nội dung email").Wait();
Gửi Mail bằng cách sử dụng Gmail
Gmail có địa chỉ server SMTP tại: smtp.gmail.com
bạn có thể tạo ra SmtpClient kết nối đến
Server này để gửi mail, thông tin để kết nối cần cung cấp bao gồm
- Server SMTP:
smtp.gmail.com
- Cổng kết nối:
587
- Ssl: phải kích hoạt
- Xác thực: Phải xác thực kết nối bằng cách cung cấp tài khoản (địa chỉ email google) và password
Thực hiện tạo SmtpClient như sau:
// Tạo SmtpClient kết nối đến smtp.gmail.com using (SmtpClient client = new SmtpClient ("smtp.gmail.com")) { client.Port = 587; // Tạo xác thực bằng địa chỉ gmail và password client.Credentials = new NetworkCredential (_gmailsend, _gmailpassword); client.EnableSsl = true; ... sử dụng client để gửi mail tại đây }
Từ đây xây dựng thêm phương thức SendMailGoogleSmtp
như sau:
namespace MailUtils { public static class MailUtils { public static async Task<bool> SendMail(string _from .... public static async Task<bool> SendMailLocalSmtp ( string _from ... /// <summary> /// Gửi email sử dụng máy chủ SMTP Google (smtp.gmail.com) /// </summary> public static async Task<bool> SendMailGoogleSmtp (string _from, string _to, string _subject, string _body, string _gmailsend, string _gmailpassword) { MailMessage message = new MailMessage ( from: _from, to: _to, subject: _subject, body: _body ); message.BodyEncoding = System.Text.Encoding.UTF8; message.SubjectEncoding = System.Text.Encoding.UTF8; message.IsBodyHtml = true; message.ReplyToList.Add (new MailAddress (_from)); message.Sender = new MailAddress (_from); // Tạo SmtpClient kết nối đến smtp.gmail.com using (SmtpClient client = new SmtpClient ("smtp.gmail.com")) { client.Port = 587; client.Credentials = new NetworkCredential (_gmailsend, _gmailpassword); client.EnableSsl = true; return await SendMail(_from, _to, _subject, _body, client); } } } }
Như vậy để gửi mail sử dụng Gmail bạn chỉ việc thực hiện:
await MailUtils.MailUtils.SendMailGoogleSmtp("mailgui@mail.com", "mailnhan@mail.com", "Chủ đề", "Nội dung", "yourgmail@gmail.com", "yourgmailpassword");
Hoặc gọi đồng bộ
MailUtils.MailUtils.SendMailGoogleSmtp("mailgui@mail.com", "mailnhan@mail.com", "Chủ đề", "Nội dung", "yourgmail@gmail.com", "yourgmailpassword").Wait();
LƯU Ý QUAN TRỌNG
Để Gmail cho phép SmtpClient kết nối đến server SMTP của nó với xác thực là tài khoản gmail của bạn, bạn cần thiết lập tài khoản email của bạn như sau:
Vào địa chỉ https://myaccount.google.com/security
Ở menu trái chọn mục Bảo mật, sau đó tại mục Quyền truy cập của ứng dụng kém an toàn phải ở chế độ bật
Đồng thời tài khoản Gmail cũng cần bật IMAP
Truy cập địa chỉ https://mail.google.com/mail/#settings/fwdandpop
Mã nguồn App Console gửi Mail: CS030_SendMail
Dùng MailKit gửi Mail trong ASP.NET với Gmail
SmtpClient mặc dù vẫn được dùng nhưng .NET đánh dấu nó lỗi thời về khuyên dùng MailKit (https://github.com/jstedfast/MimeKit). Để tích hợp thư viện MailKit bạn thực hiện các lệnh:
dotnet add package MailKit dotnet add package MimeKit
Sau đây hướng dẫn để dùng MailKit gửi mail có sử dụng Smtp Server từ Gmail.
Ta sẽ lưu thông tin cấu hình email tại config của ứng dụng:
Lưu cấu hình Email dưới khóa EmailSettings của file appsettings.json
,
nội dung như sau:
{ // các mục khác của config "MailSettings": { "Mail": "gmail của bạn ví dụ: xuanthulab.net@gmail.com", "DisplayName": "Tên Hiện Thị (ví dụ XUANTHULAB", "Password": "passowrd ở đây", "Host": "smtp.gmail.com", "Port": 587 } }
Các cấu hình này có thể ánh xạ vào thuộc tính của một lớp, hãy áp dụng bài Cấu hình ứng dụng ASP.NET
Xây dựng một lớp là MailSettings
có các thuộc tính giống config như sau:
public class MailSettings { public string Mail { get; set; } public string DisplayName { get; set; } public string Password { get; set; } public string Host { get; set; } public int Port { get; set; } }
Sau đó đăng ký vào dịch vụ hệ thống
(xem đăng ký options vào dịch vụ)
để lớp nào cần dùng MailSettings có thể Inject nó vào.
Mở file Startup.cs
cập nhật:
public class Startup { // Thêm khởi tạo để lấy IConfiguration của ứng dụng IConfiguration _configuration; public Startup (IConfiguration configuration) { _configuration = configuration; } public void ConfigureServices (IServiceCollection services) { // ... services.AddOptions (); // Kích hoạt Options var mailsettings = _configuration.GetSection ("MailSettings"); // đọc config services.Configure<MailSettings> (mailsettings); // đăng ký để Inject } // ... các phương thức khác }
Tạo dịch vụ gửi Mail và đăng ký dịch vụ vào hệ thống
Lớp MailContent
để mô tả thông tin email sẽ gửi
// Chứa thông tin Email sẽ gửi (Trường hợp này chưa hỗ trợ đính kém file) public class MailContent { public string To { get; set; } // Địa chỉ gửi đến public string Subject { get; set; } // Chủ đề (tiêu đề email) public string Body { get; set; } // Nội dung (hỗ trợ HTML) của email }
Xây dựng giao diện ISendMailService để triển khai dịch vụ
using System.Threading.Tasks; public interface ISendMailService { Task SendMail(MailContent mailContent); Task SendEmailAsync(string email, string subject, string htmlMessage); }
Triển khai ISendMailService thành lớp SendMailService với nội dung như sau
using System; using System.Threading.Tasks; using MailKit.Security; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using MimeKit; public class SendMailService : ISendMailService { private readonly MailSettings mailSettings; private readonly ILogger<SendMailService> logger; // mailSetting được Inject qua dịch vụ hệ thống // Có inject Logger để xuất log public SendMailService (IOptions<MailSettings> _mailSettings, ILogger<SendMailService> _logger) { mailSettings = _mailSettings.Value; logger = _logger; logger.LogInformation("Create SendMailService"); } // Gửi email, theo nội dung trong mailContent public async Task SendMail (MailContent mailContent) { var email = new MimeMessage (); email.Sender = new MailboxAddress(mailSettings.DisplayName, mailSettings.Mail); email.From.Add(new MailboxAddress(mailSettings.DisplayName, mailSettings.Mail)); email.To.Add (MailboxAddress.Parse (mailContent.To)); email.Subject = mailContent.Subject; var builder = new BodyBuilder(); builder.HtmlBody = mailContent.Body; email.Body = builder.ToMessageBody (); // dùng SmtpClient của MailKit using var smtp = new MailKit.Net.Smtp.SmtpClient(); try { smtp.Connect (mailSettings.Host, mailSettings.Port, SecureSocketOptions.StartTls); smtp.Authenticate (mailSettings.Mail, mailSettings.Password); await smtp.SendAsync(email); } catch (Exception ex) { // Gửi mail thất bại, nội dung email sẽ lưu vào thư mục mailssave System.IO.Directory.CreateDirectory("mailssave"); var emailsavefile = string.Format(@"mailssave/{0}.eml", Guid.NewGuid()); await email.WriteToAsync(emailsavefile); logger.LogInformation("Lỗi gửi mail, lưu tại - " + emailsavefile); logger.LogError(ex.Message); } smtp.Disconnect (true); logger.LogInformation("send mail to " + mailContent.To); } public async Task SendEmailAsync(string email, string subject, string htmlMessage) { await SendMail(new MailContent() { To = email, Subject = subject, Body = htmlMessage }); } }
Đăng ký SendMailService vào dịch vụ của hệ thống, trong
ConfigureServices
của Startup.cs thêm vào
// Đăng ký SendMailService với kiểu Transient, mỗi lần gọi dịch // vụ ISendMailService một đới tượng SendMailService tạo ra (đã inject config) services.AddTransient<ISendMailService, SendMailService>();
Từ đây bạn có thể Inject ISendMailService vào các Controller hay các PageModel ..., khi đã có ISendMailService chỉ việc gọi ISendMailService.SendMail để gửi
Gửi thử email
Trong ứng dụng ASP.NET Core đơn giản, có thể thực hiện đoạn mã kiểm tra
khi truy cập url /testmail
app.UseEndpoints (endpoints => { endpoints.MapGet ("/", async context => { await context.Response.WriteAsync ("Hello World!"); }); endpoints.MapGet("/testmail", async context => { // Lấy dịch vụ sendmailservice var sendmailservice = context.RequestServices.GetService<ISendMailService>(); MailContent content = new MailContent { To = "xuanthulab.net@gmail.com", Subject = "Kiểm tra thử", Body = "<p><strong>Xin chào xuanthulab.net</strong></p>" }; await sendmailservice.SendMail(content); await context.Response.WriteAsync("Send mail"); }); });
Mã nguồn ASP_NET_CORE/07.sendmail