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

C# WinForms 發送 Email 完整應用程式:SMTP 設定、附件、HTML/純文字雙模式

     編輯:關於C#

本文提供一個完整的 WinForms 郵件發送應用程式範例,包含 UI 介面 (寄件者、收件者、CC/BCC、主旨、內文、附件)、System.Web.Mail (舊版) 與 System.Net.Mail (現代) 兩種發送實作、SMTP 伺服器設定與常見問題排解。

UI 介面配置 (Form1.Designer.cs 精簡版)

// 控制項宣告
private TextBox txtFrom, txtTo, txtCc, txtBcc, txtSubject, txtAttachment;
private TextBox txtBody; // Multiline = true, ScrollBars = Vertical
private Button btnBrowse, btnSend, btnExit;
private OpenFileDialog openFileDialog1;

// 版面配置 (TableLayoutPanel 建議)
/*
Row 0: Label "寄件者:" + txtFrom
Row 1: Label "收件者:" + txtTo
Row 2: Label "副本:" + txtCc
Row 3: Label "密件副本:" + txtBcc
Row 4: Label "主旨:" + txtSubject
Row 5: Label "附件:" + txtAttachment + btnBrowse
Row 6: Label "內文:" + txtBody (跨欄, 高度佔大部份)
Row 7: btnSend + btnExit (置中)
*/

現代版發送邏輯 (System.Net.Mail)

using System;
using System.Net;
using System.Net.Mail;
using System.Windows.Forms;

public partial class Form1 : Form
{
    private void btnSend_Click(object sender, EventArgs e)
    {
        try
        {
            using (var msg = new MailMessage())
            {
                msg.From = new MailAddress(txtFrom.Text.Trim());
                foreach (string addr in txtTo.Text.Split(new[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries))
                    msg.To.Add(new MailAddress(addr.Trim()));
                foreach (string addr in txtCc.Text.Split(new[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries))
                    msg.CC.Add(new MailAddress(addr.Trim()));
                foreach (string addr in txtBcc.Text.Split(new[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries))
                    msg.Bcc.Add(new MailAddress(addr.Trim()));

                msg.Subject = txtSubject.Text;
                msg.Body = txtBody.Text;
                msg.IsBodyHtml = chkHtml.Checked; // 加入 CheckBox 控制

                if (!string.IsNullOrWhiteSpace(txtAttachment.Text) && File.Exists(txtAttachment.Text))
                    msg.Attachments.Add(new Attachment(txtAttachment.Text));

                using (var client = new SmtpClient())
                {
                    client.Host = "smtp.gmail.com"; // 或從設定檔讀取
                    client.Port = 587;
                    client.EnableSsl = true;
                    client.Credentials = new NetworkCredential(txtFrom.Text.Split('@')[0], txtPassword.Text); // 需加入密碼欄位
                    client.DeliveryMethod = SmtpDeliveryMethod.Network;
                    client.Timeout = 30000;

                    client.Send(msg); // 或 await client.SendMailAsync(msg)
                }
            }
            MessageBox.Show("郵件已發送!");
        }
        catch (Exception ex)
        {
            MessageBox.Show("發送失敗:" + ex.Message);
        }
    }

    private void btnBrowse_Click(object sender, EventArgs e)
    {
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
            txtAttachment.Text = openFileDialog1.FileName;
    }

    private void btnExit_Click(object sender, EventArgs e) => Application.Exit();
}

舊版實作 (System.Web.Mail) - 僅供維護舊專案參考

using System.Web.Mail;

public void SendLegacy()
{
    MailMessage msg = new MailMessage
    {
        From = txtFrom.Text,
        To = txtTo.Text,
        Cc = txtCc.Text,
        Bcc = txtBcc.Text,
        Subject = txtSubject.Text,
        Body = txtBody.Text,
        BodyFormat = chkHtml.Checked ? MailFormat.Html : MailFormat.Text
    };

    // CDO 設定
    msg.Fields.Add("https://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "1");
    msg.Fields.Add("https://schemas.microsoft.com/cdo/configuration/sendusername", txtFrom.Text.Split('@')[0]);
    msg.Fields.Add("https://schemas.microsoft.com/cdo/configuration/sendpassword", txtPassword.Text);
    msg.Fields.Add("https://schemas.microsoft.com/cdo/configuration/smtpserver", "smtp.gmail.com");
    msg.Fields.Add("https://schemas.microsoft.com/cdo/configuration/smtpserverport", "587");
    msg.Fields.Add("https://schemas.microsoft.com/cdo/configuration/smtpusessl", "true");

    if (!string.IsNullOrEmpty(txtAttachment.Text))
        msg.Attachments.Add(new MailAttachment(txtAttachment.Text));

    SmtpMail.SmtpServer = "smtp.gmail.com";
    SmtpMail.Send(msg);
}

SMTP 伺服器常見設定對照表

提供者SMTP 主機PortSSL/TLS備註
Gmailsmtp.gmail.com587STARTTLS需應用程式密碼
Outlook/Hotmailsmtp-mail.outlook.com587STARTTLS
Yahoosmtp.mail.yahoo.com465SSL
企業 Exchangemail.company.com25/587STARTTLS/無視內部設定

常見錯誤與解決

  • 5.7.0 Authentication Required:Gmail 需開啟「兩步驟驗證」並產生「應用程式密碼」,不能使用登入密碼。
  • SSL/TLS 交握失敗:.NET Framework 4.7 以下需加入 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12。
  • 附件中文檔名亂碼:attachment.ContentDisposition.FileName = MimeUtility.Encode(fileName) (需 System.Net.Mail 4.7.2+ 或 MimeKit)。
  • 大量發送被限流:加入 Thread.Sleep(1000) 或使用專業郵件服務 (SendGrid, Mailgun, Amazon SES, Postmark)。

架構升級建議

  1. 將 SMTP 設定移至 appsettings.json / web.config,支援多環境切換。
  2. 引入 FluentEmail 或 MailKit (跨平台、支援 OAuth2、IMAP/POP3)。
  3. 實作 IEmailSender 介面,搭配 DI 容器註冊,方便單元測試 (Mock)。
  4. 非同步發送 + 佇列 (Hangfire / MassTransit / Azure Queue) 避免 UI 凍結。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved