添加项目文件。
This commit is contained in:
12
EmailLib/EmailConfiguration.cs
Normal file
12
EmailLib/EmailConfiguration.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace TechHelper.Features
|
||||
{
|
||||
public static class EmailConfiguration
|
||||
{
|
||||
public static string EmailFrom { get; set; } = "1468441589@qq.com";
|
||||
public static string Password { get; set; } = "pfxhtoztjimtbahc";
|
||||
public static string SubDescribe { get; set; } = "这是你的验证凭证";
|
||||
public static string SmtpHost { get; set; } = "smtp.qq.com";
|
||||
public static int SmtpPort { get; set; } = 587;
|
||||
|
||||
}
|
||||
}
|
13
EmailLib/EmailLib.csproj
Normal file
13
EmailLib/EmailLib.csproj
Normal file
@@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MailKit" Version="4.12.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
109
EmailLib/EmailTemap.cs
Normal file
109
EmailLib/EmailTemap.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
namespace Email
|
||||
{
|
||||
public class EmailTemap
|
||||
{
|
||||
public static string _email = @"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=""utf-8"" />
|
||||
<title>{{AppName}} - Verification Code</title>
|
||||
<style>
|
||||
/* 基本的样式重置和通用样式 */
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, ""Segoe UI"", Roboto, Helvetica, Arial, sans-serif, ""Apple Color Emoji"", ""Segoe UI Emoji"", ""Segoe UI Symbol"";
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
background-color: #f4f4f4; /* 轻微的背景色 */
|
||||
}
|
||||
.container {
|
||||
max-width: 600px; /* 内容最大宽度 */
|
||||
margin: 20px auto; /* 居中 */
|
||||
background-color: #fff; /* 白色背景 */
|
||||
padding: 30px; /* 内边距 */
|
||||
border-radius: 8px; /* 圆角 */
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* 轻微阴影 */
|
||||
}
|
||||
.header {
|
||||
text-align: center; /* 头部居中 */
|
||||
margin-bottom: 30px; /* 底部外边距 */
|
||||
border-bottom: 1px solid #eee; /* 底部细线 */
|
||||
padding-bottom: 20px; /* 底部内边距 */
|
||||
}
|
||||
.header h1 { /* 修正了 h1 和 { 之间的空格 */
|
||||
color: #007bff; /* 主题色,例如蓝色 */
|
||||
font-size: 24px;
|
||||
margin: 0;
|
||||
}
|
||||
.code-box {
|
||||
text-align: center; /* 验证码框内容居中 */
|
||||
margin: 30px 0; /* 上下外边距 */
|
||||
padding: 20px; /* 内边距 */
|
||||
background-color: #e9e9e9; /* 浅灰色背景 */
|
||||
border: 1px dashed #ccc; /* 虚线边框 */
|
||||
border-radius: 4px; /* 圆角 */
|
||||
overflow: auto; /* 防止代码过长溢出 */
|
||||
}
|
||||
.verification-code {
|
||||
font-size: 28px; /* 验证码字体大小 */
|
||||
font-weight: bold; /* 加粗 */
|
||||
color: #333; /* 深灰色 */
|
||||
letter-spacing: 5px; /* 字母间距 */
|
||||
word-break: break-all; /* 防止长代码换行问题 */
|
||||
display: block; /* 独占一行 */
|
||||
}
|
||||
.instructions {
|
||||
margin-bottom: 20px; /* 底部外边距 */
|
||||
}
|
||||
.warning {
|
||||
color: #dc3545; /* 警告色,例如红色 */
|
||||
font-weight: bold; /* 加粗 */
|
||||
margin-bottom: 20px; /* 底部外边距 */
|
||||
}
|
||||
.footer {
|
||||
text-align: center; /* 底部居中 */
|
||||
margin-top: 30px; /* 顶部外边距 */
|
||||
font-size: 12px; /* 字体大小 */
|
||||
color: #888; /* 灰色 */
|
||||
border-top: 1px solid #eee; /* 顶部细线 */
|
||||
padding-top: 20px; /* 顶部内边距 */
|
||||
}
|
||||
.footer p { /* 修正了 p 和 { 之间的空格 */
|
||||
margin: 5px 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class=""container"">
|
||||
<div class=""header"">
|
||||
<h1>您的验证码</h1>
|
||||
</div>
|
||||
<p>您好,</p>
|
||||
<div class=""instructions"">
|
||||
<p>您收到这封邮件是因为您请求验证您在 <strong>{{AppName}}</strong> 的邮箱地址。</p>
|
||||
<p>请使用以下验证码完成操作:</p>
|
||||
</div>
|
||||
<div class=""code-box"">
|
||||
<span class=""verification-code"">{{VerificationCode}}</span>
|
||||
</div>
|
||||
<p class=""instructions"">请在应用程序或网站中输入此验证码。</p>
|
||||
<p class=""warning"">为了您的账户安全,请勿将此验证码透露给任何人。</p>
|
||||
<p class=""instructions"">此验证码在 {{ExpirationMinutes}} 分钟内有效。</p>
|
||||
<p>如果您没有进行此操作,请忽略本邮件。</p>
|
||||
<div class=""footer"">
|
||||
<p>这是一封自动发送的邮件,请勿直接回复。</p>
|
||||
<p>© {{AppName}}</p>
|
||||
<p>支持: <a href=""mailto:{{SupportEmail}}"">Tech Helper</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
18
EmailLib/IEmailSender.cs
Normal file
18
EmailLib/IEmailSender.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace TechHelper.Features
|
||||
{
|
||||
public interface IEmailSender
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用 MailKit 通过邮箱发送邮件
|
||||
/// </summary>
|
||||
/// <param name="toEmail">收件人邮箱地址</param>
|
||||
/// <param name="subject">邮件主题</param>
|
||||
/// <param name="body">邮件正文 (支持 HTML)</param>
|
||||
/// <returns></returns>
|
||||
public Task SendEmailAsync(string toEmail,string subject, string body);
|
||||
|
||||
public Task SendEmailAsync(string toEmail, string body);
|
||||
|
||||
public Task SendEmailAuthcodeAsync(string toEmail, string authCode);
|
||||
}
|
||||
}
|
79
EmailLib/QEmailSender.cs
Normal file
79
EmailLib/QEmailSender.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using MailKit.Net.Smtp;
|
||||
using MailKit.Security;
|
||||
using MimeKit;
|
||||
using Email;
|
||||
using System.Text;
|
||||
|
||||
namespace TechHelper.Features
|
||||
{
|
||||
public class QEmailSender : IEmailSender
|
||||
{
|
||||
public async Task SendEmailAsync(string toEmail, string subject, string body)
|
||||
{
|
||||
var secureSocketOption = SecureSocketOptions.StartTls;
|
||||
try
|
||||
{
|
||||
var message = new MimeMessage();
|
||||
message.From.Add(new MailboxAddress("TechHelper", EmailConfiguration.EmailFrom));
|
||||
message.To.Add(new MailboxAddress("", toEmail));
|
||||
message.Subject = subject;
|
||||
message.Body = new TextPart(MimeKit.Text.TextFormat.Html)
|
||||
{
|
||||
Text = body
|
||||
};
|
||||
|
||||
|
||||
using (var client = new SmtpClient())
|
||||
{
|
||||
await client.ConnectAsync(EmailConfiguration.SmtpHost, EmailConfiguration.SmtpPort, secureSocketOption);
|
||||
|
||||
// 移除 XOAUTH2 认证机制,避免某些环境下出现异常
|
||||
// 如果不加这行,某些情况下可能会遇到 MailKit.Security.AuthenticationException: XOAUTH2 is not supported
|
||||
client.AuthenticationMechanisms.Remove("XOAUTH2");
|
||||
|
||||
await client.AuthenticateAsync(EmailConfiguration.EmailFrom, EmailConfiguration.Password);
|
||||
await client.SendAsync(message);
|
||||
await client.DisconnectAsync(true);
|
||||
}
|
||||
|
||||
Console.WriteLine("邮件发送成功 (QQ 邮箱)!");
|
||||
}
|
||||
catch (TypeInitializationException ex)
|
||||
{
|
||||
Console.WriteLine("捕获到 SmtpClient 的 TypeInitializationException!");
|
||||
Console.WriteLine($"异常消息: {ex.Message}");
|
||||
|
||||
Exception? inner = ex.InnerException; // 获取第一层内部异常
|
||||
int innerCount = 1;
|
||||
while (inner != null)
|
||||
{
|
||||
Console.WriteLine($"--> 内部异常 {innerCount}: {inner.GetType().Name}");
|
||||
Console.WriteLine($"--> 内部异常消息: {inner.Message}");
|
||||
inner = inner.InnerException; // 获取下一层内部异常
|
||||
innerCount++;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"捕获到其他类型的异常: {ex.GetType().Name}");
|
||||
Console.WriteLine($"异常消息: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SendEmailAsync(string toEmail , string body)
|
||||
{
|
||||
await SendEmailAsync(toEmail, EmailConfiguration.SubDescribe, body);
|
||||
}
|
||||
|
||||
public async Task SendEmailAuthcodeAsync(string toEmail, string authCode)
|
||||
{
|
||||
string htmlTemplateString = EmailTemap._email;
|
||||
string htmlBody = htmlTemplateString
|
||||
.Replace("{{AppName}}", "TechHelper")
|
||||
.Replace("{{VerificationCode}}", authCode)
|
||||
.Replace("{{ExpirationMinutes}}", "30")
|
||||
.Replace("{{SupportEmail}}", "TechHelper");
|
||||
await SendEmailAsync(toEmail, htmlBody);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user