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;
}
}
}
}