using MailKit.Net.Smtp; using MailKit.Security; using MimeKit; namespace OASystem.API.OAMethodLib.HotmailEmail { /// /// Hotemail 服务 /// public class HotmailEmailService : IHotmailEmailService { private readonly IConfiguration _configuration; public HotmailEmailService(IConfiguration configuration) { _configuration = configuration; } public async Task SendEmailAsync(string toEmail, string subject, string htmlContent) { // 从配置读取信息 var smtpServer = _configuration["HotEmailConfig:SmtpServer"]; var smtpPort = int.Parse(_configuration["HotEmailConfig:SmtpPort"]); var senderEmail = _configuration["HotEmailConfig:SenderEmail"]; var senderName = _configuration["HotEmailConfig:SenderName"]; var appPassword = _configuration["HotEmailConfig:AppPassword"]; // 移除应用密码中的所有 "-" 分隔符 appPassword = appPassword?.Replace("-", ""); // 验证配置必填项 if (string.IsNullOrEmpty(smtpServer) || string.IsNullOrEmpty(senderEmail) || string.IsNullOrEmpty(appPassword)) { Console.WriteLine("[Email Error]: 邮件配置不完整"); return false; } var message = new MimeMessage(); message.From.Add(new MailboxAddress(senderName, senderEmail)); // 校验收件人邮箱格式,避免无效地址报错 if (!MailboxAddress.TryParse(toEmail, out var recipient)) { Console.WriteLine($"[Email Error]: 收件人邮箱格式错误 - {toEmail}"); return false; } message.To.Add(recipient); message.Subject = subject; var bodyBuilder = new BodyBuilder { HtmlBody = htmlContent }; message.Body = bodyBuilder.ToMessageBody(); using var client = new SmtpClient(); try { // 显式设置超时时间,避免连接超时 client.Timeout = 30000; // 30秒超时 // 连接服务器 (Hotmail/Outlook 必须使用 StartTls) await client.ConnectAsync(smtpServer, smtpPort, SecureSocketOptions.StartTls); // 身份验证 await client.AuthenticateAsync(senderEmail, appPassword); // 执行发送 await client.SendAsync(message); await client.DisconnectAsync(true); Console.WriteLine($"[Email Success]: 邮件已发送至 {toEmail}"); return true; } catch (Exception ex) { // 打印完整异常链,定位真实错误 var errorMsg = $"[Email Error]: {ex.Message}"; var innerEx = ex.InnerException; while (innerEx != null) { errorMsg += $"\n[Inner Error]: {innerEx.Message}"; innerEx = innerEx.InnerException; } Console.WriteLine(errorMsg); return false; } } } }