Эта статья предназначена для новичков и рассматривает микросервис отправки писем через smtp Yandex с использованием .Net Web Api и MailKit. В ней будет рассмотрено, как настроить и использовать данный микросервис для отправки писем с помощью почтового сервиса через существующий почтовый ящик Яндекса.
Ссылки для понимания и работы
Дерево проекта:

```csharp public class MailSettings { public string? DisplayName { get; set; } public string? From { get; set; } public string? UserName { get; set; } public string? Password { get; set; } public string? Host { get; set; } public int Port { get; set; } public bool UseSSL { get; set; } public bool UseStartTls { get; set; } public bool UseOAuth { get; set; } }
В данном коде определен класс MailSettings, который представляет настройки для отправки писем через smtp Yandex с использованием .Net Web Api и MailKit. В классе определены различные свойства, такие как DisplayName, From, UserName, Password, Host, Port, UseSSL, UseStartTls и UseOAuth, которые позволяют задать соответствующие параметры для подключения и аутентификации к почтовому серверу Яндекса.
namespace mailService.Models; public class MailData { // Receiver public List<string> To { get; } public List<string> Bcc { get; } public List<string> Cc { get; } // Sender public string? From { get; } public string? DisplayName { get; } public string? ReplyTo { get; } public string? ReplyToName { get; } // Content public string Subject { get; } public string? Body { get; } public MailData( List<string> to, string subject, string? body = null, string? from = null, string? displayName = null, string? replyTo = null, string? replyToName = null, List<string>? bcc = null, List<string>? cc = null ) { // Receiver To = to; Bcc = bcc ?? new List<string>(); Cc = cc ?? new List<string>(); // Sender From = from; DisplayName = displayName; ReplyTo = replyTo; ReplyToName = replyToName; // Content Subject = subject; Body = body; } }
Класс MailData представляет собой структуру данных для отправки электронных писем через smtp Yandex с использованием .Net Web Api и MailKit. Он имеет различные свойства, такие как To, Bcc, Cc, From, DisplayName, ReplyTo, ReplyToName, Subject и Body, которые позволяют указать необходимую информацию для письма, такую как получатели, отправитель, тема и содержание.
```csharp public interface IMailService { Task<bool> SendAsync(MailData mailData, CancellationToken ct); } ```
Интерфейс IMailService определяет контракт для работы с отправкой писем через smtp Yandex с использованием .Net Web Api и MailKit. Метод SendAsync принимает объект MailData и токен отмены (CancellationToken) в качестве параметров и возвращает задачу (Task) с логическим значением (bool), указывающим, было ли письмо успешно отправлено. Этот интерфейс позволяет абстрагироваться от конкретной реализации отправки писем и обеспечивает гибкость в дальнейшей работе с отправкой писем.
using MailKit.Net.Smtp; using MailKit.Security; using Microsoft.Extensions.Options; using MimeKit; using mailService.Configuration; using mailService.Models; namespace mailService.Services { public class MailService: IMailService { private readonly MailSettings _settings; public MailService(IOptions<MailSettings> settings) { _settings = settings.Value; } public async Task<bool> SendAsync(MailData mailData) { try { // Initialize a new instance of the MimeKit.MimeMessage class var mail = new MimeMessage(); #region Sender / Receiver // Sender mail.From.Add(new MailboxAddress(_settings.DisplayName, mailData.From ?? _settings.From)); mail.Sender = new MailboxAddress(mailData.DisplayName ?? _settings.DisplayName, mailData.From ?? _settings.From); // Receiver foreach (string mailAddress in mailData.To) mail.To.Add(MailboxAddress.Parse(mailAddress)); // Set Reply to if specified in mail data if(!string.IsNullOrEmpty(mailData.ReplyTo)) mail.ReplyTo.Add(new MailboxAddress(mailData.ReplyToName, mailData.ReplyTo)); // BCC // Check if a BCC was supplied in the request if (mailData.Bcc != null) { // Get only addresses where value is not null or with whitespace. x = value of address foreach (string mailAddress in mailData.Bcc.Where(x => !string.IsNullOrWhiteSpace(x))) mail.Bcc.Add(MailboxAddress.Parse(mailAddress.Trim())); } // CC // Check if a CC address was supplied in the request if (mailData.Cc != null) { foreach (string mailAddress in mailData.Cc.Where(x => !string.IsNullOrWhiteSpace(x))) mail.Cc.Add(MailboxAddress.Parse(mailAddress.Trim())); } #endregion #region Content var body = new BodyBuilder(); mail.Subject = mailData.Subject; body.HtmlBody = mailData.Body; mail.Body = body.ToMessageBody(); #endregion #region Send Mail using (var client = new SmtpClient()) { try { await client.ConnectAsync(_settings.Host, _settings.Port, SecureSocketOptions.SslOnConnect); client.AuthenticationMechanisms.Remove("XOAUTH2"); client.Authenticate(_settings.UserName, _settings.Password); await client.SendAsync(mail); } catch (Exception e) { Console.WriteLine(e); throw; } finally { await client.DisconnectAsync(true); client.Dispose(); } } #endregion return true; } catch (Exception) { return false; } } } }
Этот код представляет собой службу для отправки электронной почты с использованием библиотеки MailKit. Он включает в себя класс MailService , который реализует интерфейс IMailService .
В конструкторе класса MailService используется зависимость IOptions<MailSettings> settings , чтобы получить настройки электронной почты из конфигурации.
Метод SendAsync асинхронно отправляет электронное письмо на основе переданных данных. Он создает экземпляр класса MimeMessage и настраивает отправителя, получателя, копию, скрытую копию, тему и тело письма. Затем он использует SmtpClient для подключения к серверу SMTP, аутентификации и отправки письма.
Если отправка прошла успешно, метод возвращает true , в противном случае - false .
using mailService.Models; using mailService.Services; using Microsoft.AspNetCore.Mvc; namespace mailService.Controllers; [Route("api/[controller]")] [ApiController] public class MailController: ControllerBase { private readonly IMailService _mail; public MailController(IMailService mail) { _mail = mail; } [HttpPost("sendmail")] public async Task<IActionResult> SendMailAsync(MailData mailData) { bool result = await _mail.SendAsync(mailData); if (result) { return StatusCode(StatusCodes.Status200OK, "Mail has successfully been sent."); } else { return StatusCode(StatusCodes.Status500InternalServerError, "An error occured. The Mail could not be sent."); } } }
В данном коде представлен контроллер MailController, который отвечает за обработку HTTP-запросов для отправки электронной почты. Контроллер принимает зависимость IMailService в конструкторе и содержит метод SendMailAsync, отвечающий за отправку письма.
Метод SendMailAsync является действием, доступным по HTTP-маршруту /api/mail/sendmail и принимает объект MailData в качестве параметра. Внутри метода вызывается метод SendAsync зависимости IMailService для отправки письма. В зависимости от результата отправки, метод возвращает соответствующий статус HTTP и сообщение о результате операции.
Контроллер помечен атрибутами [Route("api/[controller]")] и [ApiController], которые определяют префикс маршрута для контроллера и обеспечивают автоматическую валидацию модели запроса.
Таким образом, данный код представляет собой контроллер API для отправки электронной почты, который использует сервис IMailService для выполнения операции отправки.
using mailService.Configuration; using mailService.Services; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.Configure<MailSettings>( builder .Configuration .GetSection(nameof(MailSettings)) ); builder.Services.AddTransient<IMailService, MailService>(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
Здесь настраивается конфигурация приложения ASP.NET Core. В данном коде применяются следующие настройки:
AddControllers()- добавляет контроллеры в контейнер зависимостей.AddEndpointsApiExplorer()- добавляет поддержку Swagger/OpenAPI для документирования API.AddSwaggerGen()- добавляет поддержку Swagger для генерации документации API.Configure<MailSettings>()- конфигурирует настройки почты из секцииMailSettingsв файле конфигурации.AddTransient<IMailService, MailService>()- регистрирует сервисIMailServiceс временным временем жизни, чтобы он мог быть использован в приложении.
Далее создается экземпляр приложения app и настраивается конвейер обработки HTTP-запросов. В зависимости от окружения (разработка или другое), применяются соответствующие настройки, такие как использование Swagger. Затем добавляются промежуточные компоненты для перенаправления HTTPS, авторизации и маршрутизации запросов к контроллерам. Наконец, приложение запускается с помощью app.Run().
Для запуска приложения, исходные данные берутся из файлов appsettings.Development.json и appsettings.json. Эти файлы содержат конфигурационные значения, такие как настройки почты, которые используются для настройки приложения. В файле appsettings.Development.json содержатся значения, применяемые во время разработки, в то время как appsettings.json содержит значения для других окружений, таких как продакшн. Эта структура конфигурации позволяет легко настраивать приложение в различных средах без необходимости изменения исходного кода. Для того что бы мои данные остались моими я приведу картинки из этих файлов, они одинаковые у меня.

Откуда взять пароль? Читайте с документации Яндекс
Тэстовые данные для отправки
{ "to": [ "shadow-greg@yandex.ru" ], "bcc": [ "gregosetrov@yandex.ru" ], "cc": [ "gregosetrov@yandex.ru" ], "from": "gregosetrov@yandex.ru", "displayName": "greg", "replyTo": "", "replyToName": "string", "subject": "string", "body": "string" }
Пожалуйста, обратите внимание, что все поля с адресами электронной почты (to, bcc, cc, from) должны быть заполнены при отправке письма. В противном случае, сервер может вернуть ошибку 500.
Заключение:
В данной статье был представлен код для создания микросервиса отправки писем через SMTP Yandex с использованием библиотеки MailKit в .NET Web API. Были показаны основные компоненты кода, такие как класс MailService для отправки писем, контроллер MailController для обработки HTTP-запросов и настройка конфигурации приложения.
Код предоставляет пример реализации функциональности отправки писем с помощью библиотеки MailKit и демонстрирует использование интерфейсов и зависимостей для обеспечения расширяемости и тестируемости. Были рассмотрены основные шаги отправки письма, включая создание объекта MimeMessage, настройку отправителя и получателя, подключение к серверу SMTP и отправку письма.
Также были предоставлены примеры данных для тестирования отправки писем, а также информация о том, откуда можно получить пароль для авторизации при использовании почты Яндекс.
В целом, представленный код и описание позволяют разработчикам создать микросервис для отправки писем с использованием SMTP Yandex и библиотеки MailKit в .NET Web API. Это может быть полезно для различных проектов, где требуется отправка электронных писем из приложения.
