.NET Core使用FluentEmail發(fā)送郵件的示例代碼
前言
在實(shí)際的項(xiàng)目開發(fā)中,我們會(huì)遇到許多需要通過程序發(fā)送郵件的場(chǎng)景,比如異常報(bào)警、消息、進(jìn)度通知等等。一般情況下我們使用原生的SmtpClient類庫居多,它能滿足我們絕大多數(shù)場(chǎng)景。但是使用起來不夠簡潔,許多場(chǎng)景需要我們自行封裝方法去實(shí)現(xiàn),而且代碼量非??捎^。慶幸的是,我們有一款非常棒的組件,能滿足我們絕大多數(shù)應(yīng)用場(chǎng)景,而且使用簡單功能強(qiáng)大,就是我們今天要說的FluentEmail,這也是我們實(shí)際在項(xiàng)目中正在使用的郵件發(fā)送組件。如果你們?cè)?Net Core中有發(fā)送郵件的需求,也推薦去嘗試一下。
FluentEmail
FluentEmail是一款在GitHub上開源免費(fèi)的支持.Net和.Net Core郵件發(fā)送組件,目前已有1K多的Star,而且近兩年隨著.Net Core的日益成熟,它的Star增長趨勢(shì)還是非常迅猛的。它在GitHub地址是https://github.com/lukencode/FluentEmail,它的功能非常強(qiáng)大而且非常實(shí)用,支持Razor的郵件模板和支持使用SendGrid,MailGun,SMTP發(fā)送郵件,而且使用也非常簡單。
Nuget組件
FluentEmail功能強(qiáng)大,而且對(duì)不同場(chǎng)景的支持都有獨(dú)立的Nuget包,這種低耦合的拆分不僅使得依賴非常清晰,而且避免引入不需要的代碼,具體功能包含在以下的組件包中
- FluentEmail.Core - 基礎(chǔ)核心包,包含了基礎(chǔ)的模型定義和默認(rèn)的設(shè)置,而且以下的引用包都包含了這個(gè)核心包。
- FluentEmail.Smtp - 使用SMTP服務(wù)發(fā)送郵件的程序包。
- FluentEmail.Razor - 通過Razor模板生成郵件發(fā)送內(nèi)容。
- FluentEmail.Mailgun - 使用Mailgun的Rest接口發(fā)送郵件。
- FluentEmail.SendGrid - 使用SendGrid接口發(fā)送郵件。
- FluentEmail.Mailtrap - 發(fā)送郵件Mailtrap, 使用的是FluentEmail.Smtp包進(jìn)行發(fā)送.
- FluentEmail.MailKit - 使用MailKit郵件庫發(fā)送郵件。
普通郵件方式
接下來我們就演示一下如何使用FluentEmail發(fā)送郵件,由于我們實(shí)際業(yè)務(wù)中大多數(shù)都使用的SMTP的方式發(fā)送郵件,所以我們就以此為做演示,首先我們?cè)陧?xiàng)目中引入FluentEmail.Smtp包,目前最新版本為2.8.0
<PackageReference Include="FluentEmail.Smtp" Version="2.8.0" />
接下來我們就可以愉快的寫代碼了,它的編碼使用方式非常簡單而且非常簡潔,主要通過鏈?zhǔn)骄幊痰姆绞?/p>
//如果使用smtp服務(wù)發(fā)送郵件必須要設(shè)置smtp服務(wù)信息 SmtpClient smtp = new SmtpClient { //smtp服務(wù)器地址(我這里以126郵箱為例,可以依據(jù)具體你使用的郵箱設(shè)置) Host = "smtp.126.com", UseDefaultCredentials = true, DeliveryMethod = SmtpDeliveryMethod.Network, //這里輸入你在發(fā)送smtp服務(wù)器的用戶名和密碼 Credentials = new NetworkCredential("郵箱用戶名", "郵箱密碼") }; //設(shè)置默認(rèn)發(fā)送信息 Email.DefaultSender = new SmtpSender(smtp); var email = Email //發(fā)送人 .From("zhangsan@126.com") //收件人 .To("lisi@qq.com") //抄送人 .CC("admin@126.com") //郵件標(biāo)題 .Subject("郵件標(biāo)題") //郵件內(nèi)容 .Body("郵件內(nèi)容"); //依據(jù)發(fā)送結(jié)果判斷是否發(fā)送成功 var result = email.Send(); //或使用異步的方式發(fā)送 //await email.SendAsync(); if (result.Successful) { //發(fā)送成功邏輯 } else { //發(fā)送失敗可以通過result.ErrorMessages查看失敗原因 }
如果你發(fā)送的內(nèi)容中包含html格式的內(nèi)容可以使用如下方式
var email = Email //發(fā)送人 .From("zhangsan@126.com") //收件人 .To("lisi@qq.com") //抄送人 .CC("admin@126.com") //郵件標(biāo)題 .Subject("郵件標(biāo)題") //只需要額外設(shè)置第二個(gè)參數(shù)為true即可 .Body("<h1 align=\"center\">.NET大法好</h1><p>是的,這一點(diǎn)毛病都沒有</p>",true); //發(fā)送 var result = email.Send();
這個(gè)我們通過點(diǎn)擊查看Body的方法聲明即可得知第二個(gè)參數(shù)是用來表示內(nèi)容是否為html格式,默認(rèn)為false
IFluentEmail Body (string body, bool isHtml = false);
如果郵件的收件人為多個(gè)郵箱地址的話,可以采用To方法的另一個(gè)重載方法可以接受List<FluentEmail.Core.Models.Address>
var email = Email //發(fā)送人 .From("zhangsan@126.com") //郵件標(biāo)題 .Subject("郵件標(biāo)題") //郵件內(nèi)容 .Body("<h1 align=\"center\">.NET大法好</h1><p>是的,一點(diǎn)毛病都沒有</p>",true); //構(gòu)建多個(gè)接收人郵箱 string toUserStr = "oldwang@126.com;xiaoming@163.com;xiaoli@qq.com"; List<FluentEmail.Core.Models.Address> toUsers = toUserStr.Split(";") .Select(i => new FluentEmail.Core.Models.Address { EmailAddress = i }).ToList(); //支持傳入Address集合 email.To(toUsers) //抄送人集合 .CC(toUsers); //發(fā)送 var result = email.Send();
如果我們需要在發(fā)送的郵件中添加一個(gè)附件的話,可以使用Attache方法添加附件
var email = Email //發(fā)送人 .From("zhangsan@qq.com") //收件人 .To("lisi@126.com") //抄送人 .CC("admin@126.com") //郵件標(biāo)題 .Subject("關(guān)于.Net Core怎么樣") //郵件內(nèi)容 .Body("<h1 align=\"center\">.NET Core</h1><p>.Net Core很優(yōu)秀嗎?是的,一點(diǎn)毛病都沒有?。?!</p>",true); //構(gòu)建附件 var stream = new MemoryStream(); var sw = new StreamWriter(stream); sw.WriteLine("您好,這是文本里的內(nèi)容"); sw.Flush(); stream.Seek(0, SeekOrigin.Begin); var attachment = new FluentEmail.Core.Models.Attachment { Data = stream, ContentType = "text/plain", Filename = "Hello.txt" }; //添加附件 email.Attach(attachment); var result = email.Send();
如果需要添加多個(gè)附件的話Attach方法支持傳入Attachment集合
//構(gòu)建附件 var stream = new MemoryStream(); var sw = new StreamWriter(stream); sw.WriteLine("您好,這是文本里的內(nèi)容"); sw.Flush(); stream.Seek(0, SeekOrigin.Begin); //附件1 var attachment = new FluentEmail.Core.Models.Attachment { Data = stream, ContentType = "text/plain", Filename = "Hello.txt" }; //附件2 var attachment2 = new FluentEmail.Core.Models.Attachment { Data = File.OpenRead(@"D:\test.txt"), ContentType = "text/plain", Filename = "test.txt" }; //添加附件 email.Attach(new List<FluentEmail.Core.Models.Attachment> { attachment, attachment2 }); var result = email.Send();
使用Razor模板
上面的內(nèi)容我們介紹了使用FluentEmail使用常規(guī)的方式發(fā)送郵件,但是有時(shí)候我們需要發(fā)送一些內(nèi)容是動(dòng)態(tài)的或者發(fā)送一些樣式比較復(fù)雜html網(wǎng)頁內(nèi)容。通常我們使用原生的SmptClient的時(shí)候都是通過拼接html代碼方式,但是這種方式相對(duì)來說比較費(fèi)時(shí)費(fèi)力,對(duì)于.Net程序員來說Razor引擎是我們構(gòu)建動(dòng)態(tài)html頁面最熟悉的方式,而FluentEmail正是為我們提供了Razor模板的支持。首先,我們?cè)谥暗幕A(chǔ)上引入FluentEmail.Razor模板支持組件
<PackageReference Include="FluentEmail.Razor" Version="2.8.0" />
由于ASP.NET Core2.2開始默認(rèn)是使用的視圖編譯功能,視圖會(huì)編譯成 項(xiàng)目名稱.Views.dll,但是FluentEmail.Razor又需要讀取視圖文件的內(nèi)容,所以要在csproj文件中添加以下內(nèi)容
<MvcRazorExcludeRefAssembliesFromPublish>true</MvcRazorExcludeRefAssembliesFromPublish>
然后我們就可以使用Razor模板生成郵件內(nèi)容,具體的使用方式
//聲明使用razor的方式 Email.DefaultRenderer = new RazorRenderer(); //razor內(nèi)容 var template = "你好@Model.Name先生, 請(qǐng)核實(shí)您的電話號(hào)碼是否為@Model.Phone"; var email = Email .From("lisi@126.com") .To("zhangsan@qq.com") .Subject("手機(jī)號(hào)核實(shí)") //傳遞自定義POCO類 //.UsingTemplate<UserInfo>(template, new UserInfo { Name = "張三", Phone嗎 = "100110119120" }) //或傳遞匿名對(duì)象 .UsingTemplate(template, new { Name = "張三", Phone嗎 = "100110119120" }); var result = await email.SendAsync();
當(dāng)然它支持的方式不僅僅只是Razor字符串,還可以傳遞Razor視圖文件
var email = Email .From("lisi@126.com") .To("zhangsan@qq.com") .Subject("手機(jī)號(hào)核實(shí)") //傳遞自定義POCO類 //.UsingTemplateFromFile<UserInfo>($"{Directory.GetCurrentDirectory()}/template.cshtml", // new UserInfo { Name = "張三", Phone嗎 = "100110119120" }); //第一個(gè)參數(shù)為視圖文件位置,第二個(gè)參數(shù)為模型對(duì)象 .UsingTemplateFromFile($"{Directory.GetCurrentDirectory()}/template.cshtml", new { Name = "張三", Phone嗎 = "100110119120" }); var result = await email.SendAsync();
FluentEmail.Razor之所以能夠支持強(qiáng)大的Razor模板引擎,主要是得益于它內(nèi)部集成了RazorLight,這是一款非常強(qiáng)大的Razor引擎,可以將Razor模板字符串或者Razor視圖文件解析成具體的字符串結(jié)果,具體詳情可參閱RazorLight官方GitHub地址https://github.com/toddams/RazorLight,目前正式版并不支持.Net Core,可以選擇下載beta版本
Install-Package RazorLight -Version 2.0.0-beta10
它的使用方式也非常簡單
//razor字符串的方式 var engine = new RazorLightEngineBuilder() .UseEmbeddedResourcesProject(typeof(Program)) .UseMemoryCachingProvider() .Build(); string template = "Hello, @Model.Name. Welcome to RazorLight repository"; ViewModel model = new ViewModel {Name = "John Doe"}; //result就是解析后的字符串 string result = await engine.CompileRenderStringAsync("templateKey", template, model);
或使用razor視圖文件的方式
var engine = new RazorLightEngineBuilder() .UseFileSystemProject("${Directory.GetCurrentDirectory()}") .UseMemoryCachingProvider() .Build(); var model = new {Name = "John Doe"}; string result = await engine.CompileRenderAsync("template.cshtml", model);
當(dāng)然它支持的方式不僅僅只有這兩種,無論是使用便捷程度還是功能上都非常的強(qiáng)大,有興趣的同學(xué)可以自行查閱RazorLight的GitHub地址,講解的還是非常詳細(xì)的。在這里就不在過多的討論關(guān)于RazorLight的使用方式了。
關(guān)于發(fā)送的郵件內(nèi)容,這里有一個(gè)非常重要的點(diǎn)需要友情提示一下公共郵箱運(yùn)營商比如網(wǎng)易或騰訊,有的可能需要手動(dòng)開啟SMTP服務(wù),具體如何設(shè)置可以參考http://chabaoo.cn/diannaojichu/520949.html一文。還有一點(diǎn)也比較重要如果你使用公共郵箱運(yùn)營商的郵箱那么他們會(huì)對(duì)郵件的標(biāo)題和內(nèi)容限制比較大,可能出現(xiàn)的問題比較多,而且開啟Smtp服務(wù)需要發(fā)送短信認(rèn)證才能開啟。好在大部分公司都有自己的郵件系統(tǒng),在實(shí)際發(fā)送郵件的過程中可能不會(huì)存在這么多的問題。
結(jié)合依賴注入使用
在使用.Net Core的實(shí)際開發(fā)中,依賴注入已經(jīng)成為了必不可少的開發(fā)模式。如果你正在使用.Net Core開發(fā)項(xiàng)目,但是你還沒有接觸依賴注入,那么需要你先自行反省一下。FluentEmail作為一款與時(shí)俱進(jìn)的組件,也可以結(jié)合依賴注入使用,使用這種方式我們可以在注冊(cè)的時(shí)候統(tǒng)一的配置一些默認(rèn)的設(shè)置。這波操作就不需要額外引入一些別的包了,如果你需要使用Smtp就引入FluentEmail.Smtp包,如果你需要使用Razor模板就引入FluentEmail.Razor包,關(guān)于注入的這一部分的功能其實(shí)是包含在FluentEmail.Core包里面的
public void ConfigureServices(IServiceCollection services) { SmtpClient smtp = new SmtpClient { //smtp服務(wù)器地址(我這里以126郵箱為例,可以依據(jù)具體你使用的郵箱設(shè)置) Host = "smtp.qq.com", UseDefaultCredentials = true, DeliveryMethod = SmtpDeliveryMethod.Network, //這里輸入你在發(fā)送smtp服務(wù)器的用戶名和密碼 Credentials = new NetworkCredential("zhangsan@qq.com", "zhangsan") }; //注入的時(shí)候可以添加一些默認(rèn)的設(shè)置 services //設(shè)置默認(rèn)發(fā)送用戶 .AddFluentEmail("zhangsan@qq.com") //添加razor模板支持 //.AddRazorRenderer($"{Directory.GetCurrentDirectory()}/Views") .AddRazorRenderer() //配置默認(rèn)的smtp服務(wù)信息 .AddSmtpSender(smtp); }
在需要發(fā)送郵件的類中直接注入IFluentEmail,不必驚慌咱們上面使用的Email這個(gè)類其實(shí)就是實(shí)現(xiàn)了IFluentEmail這個(gè)接口,所以使用方式上是完全一致的
public async Task<IActionResult> SendEmail([FromServices]IFluentEmail email) { var result = await email//發(fā)送人 //發(fā)送人 .From("zhangsan@126.com") //收件人 .To("lisi@qq.com") //抄送人 .CC("admin@126.com") //郵件標(biāo)題 .Subject("郵件標(biāo)題") //郵件內(nèi)容 .Body("郵件內(nèi)容").SendAsync(); return View(); }
如果你需要發(fā)送Razor視圖模板相關(guān)的內(nèi)容,也還是那個(gè)熟悉的配方那個(gè)熟悉的味道,沒有任何的不同,只是省略了一些我們?cè)谧?cè)的時(shí)候添加的一些默認(rèn)配置
public async Task<IActionResult> SendEmail([FromServices]IFluentEmail email) { var result = await email//發(fā)送人 //發(fā)送人 .From("zhangsan@126.com") //收件人 .To("lisi@qq.com") //抄送人 .CC("admin@126.com") //郵件標(biāo)題 .Subject("郵件標(biāo)題") //郵件內(nèi)容 .Body("郵件內(nèi)容").SendAsync(); return View(); }
總結(jié)
關(guān)于FluentEmail的基本使用方式我們就介紹到這里,我個(gè)人感覺它自身的功能還是非常強(qiáng)大的,而且使用起來非常的簡單。說實(shí)話在之前我沒接觸到FluentEmail之前,我經(jīng)常在園子里看到其他語言集成發(fā)送郵件的組件,確實(shí)非常強(qiáng)大,比如在springboot中集成spring-boot-starter-mail真的是非常的便捷。后來無意中接觸到了FluentEmail心里還是蠻欣慰的,一是它強(qiáng)大的功能和易用性,其次是可以去結(jié)合.Net Core進(jìn)一步優(yōu)化了它的使用方式,至少在.Net和.Net Core中我們也擁有一款非常便捷的郵件發(fā)送組件。FluentEmail的作者也呼吁更多的開發(fā)者能夠了解并參與到FluentEmail開發(fā)和實(shí)踐中去,最后再次貼上它的GitHub地址https://github.com/lukencode/FluentEmail
到此這篇關(guān)于.NET Core使用FluentEmail發(fā)送郵件的示例代碼的文章就介紹到這了,更多相關(guān).NET Core 發(fā)送郵件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
asp.net實(shí)現(xiàn)的群發(fā)郵件功能詳解
這篇文章主要介紹了asp.net實(shí)現(xiàn)的群發(fā)郵件功能,結(jié)合具體實(shí)例形式分析了asp.net基于SMTP服務(wù)群發(fā)QQ郵件的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2017-05-05.NET?Core控制臺(tái)應(yīng)用ConsoleApp讀取appsettings.json配置文件
這篇文章介紹了.NET?Core控制臺(tái)應(yīng)用ConsoleApp讀取appsettings.json配置文件的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07asp.net中動(dòng)態(tài)改變網(wǎng)頁標(biāo)題的代碼
asp.net中動(dòng)態(tài)改變網(wǎng)頁標(biāo)題的代碼,需要的朋友可以參考下。2011-02-02