首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 發送 Email 完整類別:支援純文字/HTML、附件、SSL 與身分驗證

     編輯:關於C#

System.Web.Mail 是 .NET Framework 1.x/2.0 時代的郵件發送 API,雖已標記過時 (Obsolete),但在維護舊專案時仍常見。現代專案請改用 System.Net.Mail.SmtpClient。本文提供兩個版本的完整封裝類別供參考。

舊版:System.Web.Mail 封裝 (相容 .NET 2.0)

using System;
using System.Collections;
using System.Web.Mail;

public class LegacyMailSender
{
    public void SendTextMail(string from, string password, string to, string subject,
                             MailPriority priority, string body, string smtpServer, ArrayList attachments)
    {
        SendMail(from, password, to, subject, priority, body, smtpServer, attachments, MailFormat.Text);
    }

    public void SendHtmlMail(string from, string password, string to, string subject,
                             MailPriority priority, string body, string smtpServer, ArrayList attachments)
    {
        SendMail(from, password, to, subject, priority, body, smtpServer, attachments, MailFormat.Html);
    }

    private void SendMail(string from, string password, string to, string subject,
                          MailPriority priority, string body, string smtpServer,
                          ArrayList attachments, MailFormat format)
    {
        MailMessage msg = new MailMessage
        {
            From = from,
            To = to,
            Subject = subject,
            Priority = priority,
            BodyFormat = format,
            Body = body
        };

        // 基本驗證 (CDO 配置)
        msg.Fields.Add("https://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "1"); // basic
        msg.Fields.Add("https://schemas.microsoft.com/cdo/configuration/sendusername", from.Split('@')[0]);
        msg.Fields.Add("https://schemas.microsoft.com/cdo/configuration/sendpassword", password);
        msg.Fields.Add("https://schemas.microsoft.com/cdo/configuration/smtpserverport", "25");

        foreach (string file in attachments)
            if (System.IO.File.Exists(file))
                msg.Attachments.Add(new MailAttachment(file));

        SmtpMail.SmtpServer = smtpServer;
        SmtpMail.Send(msg);
    }
}

現代版:System.Net.Mail 封裝 (.NET 2.0+ / .NET Core / .NET 5+)

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Mail;
using System.Threading.Tasks;

public class ModernMailSender
{
    private readonly SmtpClient _client;

    public ModernMailSender(string host, int port, string user, string password, bool enableSsl = true)
    {
        _client = new SmtpClient(host, port)
        {
            Credentials = new NetworkCredential(user, password),
            EnableSsl = enableSsl,
            DeliveryMethod = SmtpDeliveryMethod.Network,
            Timeout = 30000
        };
    }

    public async Task SendAsync(string from, string to, string subject, string body,
                                bool isHtml, IEnumerable attachmentPaths = null)
    {
        using (var msg = new MailMessage(from, to, subject, body))
        {
            msg.IsBodyHtml = isHtml;
            msg.Priority = MailPriority.Normal;

            if (attachmentPaths != null)
                foreach (var path in attachmentPaths)
                    if (System.IO.File.Exists(path))
                        msg.Attachments.Add(new Attachment(path));

            await _client.SendMailAsync(msg);
        }
    }

    // 同步版本
    public void Send(string from, string to, string subject, string body,
                     bool isHtml, IEnumerable attachmentPaths = null)
    {
        SendAsync(from, to, subject, body, isHtml, attachmentPaths).GetAwaiter().GetResult();
    }
}

使用範例

// 現代版用法
var sender = new ModernMailSender("smtp.gmail.com", 587, "user@gmail.com", "app-password", true);
sender.Send(
    from: "user@gmail.com",
    to: "target@example.com",
    subject: "測試信件",
    body: "<h1>HTML 內容</h1><p>支援中文</p>",
    isHtml: true,
    attachmentPaths: new[] { @"C:\temp\report.pdf" }
);

常見問題與解決方案

問題原因與對策
Gmail/Outlook 拒絕登入需開啟「低安全性應用程式存取」或使用「應用程式密碼」/ OAuth 2.0
附件中文檔名亂碼使用 Attachment(path, MediaTypeNames.Application.Octet) 並手動設定 ContentDisposition.FileName = System.Net.Mime.MimeUtility.Encode(fileName)
大量發送被封鎖加入發送間隔、使用專業郵件服務 (SendGrid, Mailgun, Amazon SES)
SSL/TLS 協定錯誤.NET 4.7+ 預設支援 TLS 1.2,舊版需 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12

最佳實務摘要

  • 新專案一律使用 System.Net.Mail + async/await。
  • 密碼勿寫死於程式碼,請從 Key Vault、環境變數或設定檔讀取。
  • HTML 郵件建議同時提供純文字替代版本 (AlternateViews)。
  • 大量發送請實作佇列與重試機制 (Polly、Hangfire、MassTransit)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved