【发布时间】:2022-01-18 03:23:49
【问题描述】:
我有一个包含多个项目的 .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 这样的资产包含在生产版本中?
它会包含在Services 项目的.dll 捆绑包中吗?
编辑:我已将 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
【问题讨论】:
标签: c# .net email dev-to-production