C#使用System.Net庫實(shí)現(xiàn)自動(dòng)發(fā)送郵件功能
一、基本概念
在C#編程環(huán)境中,實(shí)現(xiàn)郵件發(fā)送功能是一項(xiàng)常見的需求,無論是Web應(yīng)用程序還是Windows窗體應(yīng)用程序,郵件服務(wù)都能幫助用戶進(jìn)行信息的傳遞和溝通。使用C#中的System.Net庫,來實(shí)現(xiàn)自動(dòng)發(fā)送郵件的功能。
二、郵箱授權(quán)
下面進(jìn)行郵箱的授權(quán),本篇文章使用QQ郵箱作為案列進(jìn)行示范。
發(fā)送完成按照指引將會(huì)獲得一串授權(quán)碼。將授權(quán)碼填入下面代碼的指定位置。
三、示例代碼
使用System.Net.Mail發(fā)送一封簡單的文本郵件:
using System; using System.Net; using System.Net.Mail; class EmailSender { public static void Main() { try { // 配置SMTP服務(wù)器信息(以QQ郵箱為例) string smtpServer = "smtp.qq.com"; //此處修改發(fā)送郵箱的服務(wù)器地址 int smtpPort = 587; bool enableSsl = true; string fromEmail = "your_email@qq.com";//使用的郵箱 string password = "your_password_or_auth_code"; // 此處填寫剛剛獲得的授權(quán)碼 // 創(chuàng)建郵件客戶端 using SmtpClient client = new SmtpClient(smtpServer) { Port = smtpPort, Credentials = new NetworkCredential(fromEmail, password), EnableSsl = enableSsl }; // 創(chuàng)建郵件內(nèi)容 MailMessage message = new MailMessage { From = new MailAddress(fromEmail), Subject = "測試郵件", Body = "這是一封來自C#程序的測試郵件", IsBodyHtml = false // 設(shè)置為true發(fā)送HTML郵件 }; // 添加收件人 message.To.Add("recipient@example.com"); //填入接受郵件的郵箱地址 // 發(fā)送郵件 client.Send(message); Console.WriteLine("郵件發(fā)送成功!"); } catch (Exception ex) { Console.WriteLine($"郵件發(fā)送失?。簕ex.Message}"); } } }
常見郵箱服務(wù)器配置
郵箱服務(wù)商 | SMTP服務(wù)器地址 | 端口 | SSL要求 |
---|---|---|---|
QQ郵箱 | smtp.qq.com | 587 | 是 |
163郵箱 | smtp.163.com | 465 | 是 |
Gmail | smtp.gmail.com | 587 | 是 |
Outlook | smtp.office365.com | 587 | 是 |
四、制作一個(gè)報(bào)錯(cuò)提醒功能的函數(shù)
制作一個(gè)報(bào)錯(cuò)提醒功能的函數(shù),當(dāng)現(xiàn)成的程序出現(xiàn)了問題,自動(dòng)發(fā)送郵件提醒程序員進(jìn)行遠(yuǎn)程處理。打工的牛馬制作一個(gè)鞭子抽自己起來干活。實(shí)現(xiàn)效果如下
using System; using System.Diagnostics; using System.Net; using System.Net.Mail; using System.Security.Cryptography; using System.Text; class EmailSender { // ======== 配置信息 ======== static string smtpServer = "smtp.qq.com"; static int smtpPort = 587; static bool enableSsl = true; static string fromEmail = "填入發(fā)送的郵箱"; //發(fā)送郵箱 static string password = "郵箱授權(quán)碼"; // QQ郵箱需要授權(quán)碼 static string incomingEmail = "接受郵件的郵箱地址";//收件郵箱地址 private static readonly object fileLock = new object(); private const string LogDirectory = "EmailSendLogs"; /// <summary> /// 報(bào)警信息發(fā)送至郵箱 /// </summary> /// <param name="alertLevel">報(bào)警級(jí)別支持: /// CRITICAL:嚴(yán)重問題(紅色) /// HIGH:高級(jí)別問題(橙色) /// MEDIUM:中等問題(黃色) /// LOW:低級(jí)別通知(綠色) /// </param> /// <param name="alertContent">報(bào)警內(nèi)容</param> /// <param name="errorDetails">錯(cuò)誤詳情</param> /// <param name="attachmentPaths">附件</param> public static void SendToEmail(string alertLevel, string alertContent, string errorDetails = null, string[] attachmentPaths = null) { try { //1和2是會(huì)在程序運(yùn)行的文件夾中生成一個(gè)日志文件,當(dāng)同一個(gè)報(bào)錯(cuò)今天已經(jīng)發(fā)送過了,將會(huì) //不再發(fā)送,防止報(bào)錯(cuò)一直觸發(fā)然后一直給自己發(fā)送郵件,這樣子抽牛馬干活打在自己身上就太痛了 // ===== 1. 生成錯(cuò)誤唯一標(biāo)識(shí) ===== string errorHash = GenerateErrorHash(alertContent, errorDetails); // ===== 2. 檢查是否已發(fā)送過 ===== if (IsAlreadySentToday(errorHash)) { Console.WriteLine("相同錯(cuò)誤今日已發(fā)送過,不再重復(fù)發(fā)送"); return; } // ======== 創(chuàng)建郵件客戶端 ======== using SmtpClient client = new SmtpClient(smtpServer) { Port = smtpPort, Credentials = new NetworkCredential(fromEmail, password), EnableSsl = enableSsl }; // ======== 報(bào)警級(jí)別顏色映射 ======== var alertLevelInfo = new Dictionary<string, (string color, string emoji)> { { "CRITICAL", ("#d32f2f", "??") }, // 紅色 { "HIGH", ("#f57c00", "??") }, // 橙色 { "MEDIUM", ("#ffa000", "?") }, // 黃色 { "LOW", ("#4caf50", "??") } // 綠色 }; // 獲取當(dāng)前報(bào)警級(jí)別的顏色和表情符號(hào) var (color, emoji) = alertLevelInfo.ContainsKey(alertLevel) ? alertLevelInfo[alertLevel] : ("#666666", "??"); // ======== 構(gòu)建郵件內(nèi)容 ======== string htmlBody = $@" <!DOCTYPE html> <html> <head> <style> .card {{ border: 1px solid #e0e0e0; padding: 20px; max-width: 800px; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }} .header {{ border-bottom: 2px solid {color}; padding-bottom: 10px; margin-bottom: 20px; }} .alert-level {{ color: {color}; font-weight: bold; }} pre {{ background: #f8f9fa; padding: 15px; border-radius: 4px; overflow-x: auto; }} </style> </head> <body> <div class='card'> <div class='header'> <h2>{emoji} 系統(tǒng)報(bào)警 - {alertLevel}</h2> </div> <table> <tr><th>報(bào)警時(shí)間:</th><td>{DateTime.Now:yyyy-MM-dd HH:mm:ss}</td></tr> <tr><th>報(bào)警級(jí)別:</th><td class='alert-level'>{alertLevel}</td></tr> </table> <h3>▌ 報(bào)警內(nèi)容</h3> <p>{alertContent}</p> {(errorDetails != null ? $@" <h3>▌ 錯(cuò)誤詳情</h3> <pre>{errorDetails}</pre> " : "")} <div style='margin-top: 25px; color: #666; font-size: 0.9em;'> <hr> <p>此郵件由系統(tǒng)自動(dòng)發(fā)送,請(qǐng)勿直接回復(fù)</p> <p>負(fù)責(zé)人:牛馬程序員 (123456@niuma.com)</p> </div> </div> </body> </html>"; // ======== 創(chuàng)建郵件消息 ======== MailMessage message = new MailMessage { From = new MailAddress(fromEmail), Subject = $"{emoji} 系統(tǒng)報(bào)警 - {alertLevel}", Body = htmlBody, IsBodyHtml = true }; // 添加收件人 message.To.Add(incomingEmail); // 添加附件 if (attachmentPaths != null) { foreach (var path in attachmentPaths) { if (File.Exists(path)) { message.Attachments.Add(new Attachment(path)); } } } // ======== 發(fā)送郵件 ======== client.Send(message); // ===== 4. 記錄發(fā)送日志 ===== LogError(errorHash, alertLevel, alertContent, errorDetails); Console.WriteLine("郵件發(fā)送成功!"); } catch (Exception ex) { Console.WriteLine($"郵件發(fā)送失?。簕ex.Message}"); } } /// <summary> /// 創(chuàng)建唯一加密標(biāo)識(shí)符號(hào) /// </summary> /// <param name="content"></param> /// <param name="details"></param> /// <returns></returns> private static string GenerateErrorHash(string content, string details) { using MD5 md5 = MD5.Create(); string rawData = $"{content}|{details}"; byte[] hashBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(rawData)); return BitConverter.ToString(hashBytes).Replace("-", ""); } /// <summary> /// 檢查是否已經(jīng)發(fā)送過 /// </summary> /// <param name="errorHash"></param> /// <returns></returns> private static bool IsAlreadySentToday(string errorHash) { string todayLogFile = GetTodayLogFilePath(); lock (fileLock) { if (!File.Exists(todayLogFile)) return false; foreach (string line in File.ReadAllLines(todayLogFile)) { if (line.StartsWith(errorHash)) { return true; } } } return false; } //記錄報(bào)警內(nèi)容 private static void LogError(string errorHash, string level, string content, string details) { string logEntry = $"{errorHash}|{DateTime.Now:yyyy-MM-dd HH:mm:ss}|" + $"{level}|{content}|{details}\n"; lock (fileLock) { EnsureLogDirectoryExists(); File.AppendAllText(GetTodayLogFilePath(), logEntry); } } //獲取報(bào)警日志地址 private static string GetTodayLogFilePath() { return Path.Combine(LogDirectory, $"SnedErrorLog_{DateTime.Now:yyyyMMdd}.txt"); } //無文件創(chuàng)建文件夾 private static void EnsureLogDirectoryExists() { if (!Directory.Exists(LogDirectory)) { Directory.CreateDirectory(LogDirectory); } } public static void Main() { SendToEmail( alertLevel: "HIGH", alertContent: "數(shù)據(jù)庫益處請(qǐng)?zhí)幚恚赡軐?dǎo)致系統(tǒng)響應(yīng)緩慢。", errorDetails: "TimeoutException: Could not connect to database.\n at DatabaseService.Connect() Line 123", attachmentPaths: new[] { "error.log" }); SendToEmail( alertLevel: "HIGH", alertContent: "數(shù)據(jù)庫連接池使用率超過90%,可能導(dǎo)致系統(tǒng)響應(yīng)緩慢。", errorDetails: "TimeoutException: Could not connect to database.\n at DatabaseService.Connect() Line 123", attachmentPaths: new[] { "error.log" }); } }
到此這篇關(guān)于C#使用System.Net庫實(shí)現(xiàn)自動(dòng)發(fā)送郵件功能的文章就介紹到這了,更多相關(guān)C#自動(dòng)發(fā)送郵件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#設(shè)計(jì)模式之適配器模式與裝飾器模式的實(shí)現(xiàn)
創(chuàng)建型設(shè)計(jì)模式主要是為了解決創(chuàng)建對(duì)象的問題,而結(jié)構(gòu)型設(shè)計(jì)模式則是為了解決已有對(duì)象的使用問題。本文將用C#語言實(shí)現(xiàn)結(jié)構(gòu)型設(shè)計(jì)模式中的適配器模式與裝飾器模式,感興趣的可以了解一下2022-04-04C# .net core HttpClientFactory用法及說明
這篇文章主要介紹了C# .net core HttpClientFactory用法及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11解析如何正確使用SqlConnection的實(shí)現(xiàn)方法
本篇文章對(duì)如何正確使用SqlConnection的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C#如何使用PaddleOCR進(jìn)行圖片文字識(shí)別功能
PaddlePaddle(飛槳)是百度開發(fā)的深度學(xué)習(xí)平臺(tái),旨在為開發(fā)者提供全面、靈活的工具集,用于構(gòu)建、訓(xùn)練和部署各種深度學(xué)習(xí)模型,它具有開放源代碼、高度靈活性、可擴(kuò)展性和分布式訓(xùn)練等特點(diǎn),這篇文章主要介紹了C#使用PaddleOCR進(jìn)行圖片文字識(shí)別,需要的朋友可以參考下2024-04-04Unity實(shí)現(xiàn)移動(dòng)物體到鼠標(biāo)點(diǎn)擊位置
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)移動(dòng)物體到鼠標(biāo)點(diǎn)擊位置,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08