我有一個包含多個專案的 .NET Core Web API 解決方案,我將在下面發布結構和必要的路徑。
我有一個電子郵件服務,它從同一個專案的路徑中提取模板,決議它并通過電子郵件發送它。
Solution -
Core (Project Models, Context and Interfaces)
MainProject (Executed Project) -
Controllers -
EmailController.cs
Repository
Services -
Email -
templates -
ContactEmailTemplate.html
EmailService.cs
電子郵件服務如下所示:
using System;
using System.IO;
using System.Net;
using System.Net.Mail;
using Core.Email.Services;
using Core.Email.Services.Models;
using Core.Services.Response;
namespace Services.Email
{
public class EmailService : IEmailService
{
private const string SmtpAddress = "smtp.gmail.com";
private const int PortNumber = 587;
private const bool EnableSsl = true;
private const string EmailFromAddress = ""; //Sender Email Address
private const string Password = ""; //Sender Password
private const string EmailToAddress = ""; //Receiver Email Address
private const string Subject = "New Email From...";
public ServicesResponse<bool> SendEmail(EmailRequest emailRequest)
{
try
{
var mail = CreateMailMessage(emailRequest);
using var smtp = new SmtpClient(SmtpAddress, PortNumber);
smtp.Credentials = new NetworkCredential(EmailFromAddress, Password);
smtp.EnableSsl = EnableSsl;
smtp.Send(mail);
return new ServicesResponse<bool>
{
Data = true,
Exception = null,
HasError = false
};
}
catch (Exception exception)
{
return ServicesResponse<bool>.FromException(exception);
}
}
private static MailMessage CreateMailMessage(EmailRequest request)
{
return new MailMessage
{
From = new MailAddress(EmailFromAddress),
To = { EmailToAddress },
Body = CreateMailMessageFromHtml(request),
IsBodyHtml = true,
Subject = Subject
};
}
private static string CreateMailMessageFromHtml(EmailRequest request)
{
string body;
using (var reader = new StreamReader(Path.Combine(AppContext.BaseDirectory, "../../../../Services/Email/templates/ContactEmailTemplate.html"))) /* <--- Is this even going to work in prod? ?? */
{
body = reader.ReadToEnd();
}
body = body.Replace("{Name}", request.Name);
body = body.Replace("{Message}", request.Message);
return body;
}
}
一切正常,我在除錯版本的收件箱中看到了電子郵件。但是,我對這段代碼完全沒有信心:
using (var reader = new StreamReader(Path.Combine(AppContext.BaseDirectory, "../../../../Services/Email/templates/ContactEmailTemplate.html"))) /* <--- Is this even going to work in prod? ?? */
我擔心它一進入生產版本就會爆炸,感覺很臟。
如何確認生產版本中是否包含諸如 ContactEmailTemplate.html 之類的資產?
它會包含在專案的.dll捆綁包中Services嗎?
編輯:我已將 ContactEmailTemplate.html 添加為專案的嵌入式資源并重構CreateMailMessageFromHtml為以下內容
private static string CreateMailMessageFromHtml(EmailRequest request)
{
string body;
var assembly = Assembly.GetCallingAssembly();
// tried the following to get the template
var resourceStream = assembly.GetManifestResourceStream("EmbeddedResource/Email/templates/ContactEmailTemplate.html");
var resourceStream = assembly.GetManifestResourceStream("EmbeddedResource.Email.templates.ContactEmailTemplate.html");
assembly.GetManifestResourceStream("Email\\templates\\ContactEmailTemplate.html");
using (var reader = new StreamReader(resourceStream, Encoding.UTF8))
{
body = reader.ReadToEnd();
}
body = body.Replace("{Name}", request.Name);
body = body.Replace("{Message}", request.Message);
return body;
}
但是當我打開流時一切都回傳 null
uj5u.com熱心網友回復:
如果您將 HTML 檔案添加到專案并在解決方案資源管理器中單擊該檔案,您可以在屬性視窗中看到一個名為 Build Action 的屬性。如果您將其更改為嵌入資源,該檔案將(一旦編譯)存在于 DLL 中,因此始終可用。
確定作為嵌入式資源交付的所有檔案(并獲取您的全名)
var allResourceNames = assembly.GetManifestResourceNames();
我為你創建了一個示例專案來演示用法:https : //github.com/nikneem/embedded-resource-example
通過流打開檔案:
using (var stream = assembly.GetManifestResourceStream(resourceName))
uj5u.com熱心網友回復:
我遵循了@Eduard Keilhoz 的回答。我嵌入了 HTML 檔案,將其添加到我的.csproj檔案中:
<ItemGroup>
<None Remove="Email\templates\ContactEmailTemplate.html" />
<EmbeddedResource Include="Email\templates\ContactEmailTemplate.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
然后更新CreateMailMessageFromHtml為以下內容:
private static string CreateMailMessageFromHtml(EmailRequest request)
{
string body;
var assembly = Assembly.GetCallingAssembly();
using (var reader = new StreamReader(assembly.GetManifestResourceStream("Services.Email.templates.ContactEmailTemplate.html") ?? throw new InvalidOperationException()))
{
body = reader.ReadToEnd();
}
body = body.Replace("{Name}", request.Name);
body = body.Replace("{Message}", request.Message);
return body;
}
這是為了.NET Core 5.0如果有人有興趣
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/381820.html
