是否有更好的方法在C#中生成HTML电子邮件(通过System.Net.Mail发送),而不是使用Stringbuilder执行以下操作:
string userName = "John Doe";
StringBuilder mailBody = new StringBuilder();
mailBody.AppendFormat("<h1>Heading Here</h1>");
mailBody.AppendFormat("Dear {0}," userName);
mailBody.AppendFormat("<br />");
mailBody.AppendFormat("<p>First part of the email body goes here</p>");
Run Code Online (Sandbox Code Playgroud)
等等等等?
Mar*_*nHN 176
您可以使用MailDefinition类.
这是你如何使用它:
MailDefinition md = new MailDefinition();
md.From = "test@domain.com";
md.IsBodyHtml = true;
md.Subject = "Test of MailDefinition";
ListDictionary replacements = new ListDictionary();
replacements.Add("{name}", "Martin");
replacements.Add("{country}", "Denmark");
string body = "<div>Hello {name} You're from {country}.</div>";
MailMessage msg = md.CreateMailMessage("you@anywhere.com", replacements, body, new System.Web.UI.Control());
Run Code Online (Sandbox Code Playgroud)
另外,我写了一篇关于如何使用MailDefinition类使用模板在C#中生成HTML电子邮件正文的博文.
Ant*_*nes 25
使用System.Web.UI.HtmlTextWriter类.
StringWriter writer = new StringWriter();
HtmlTextWriter html = new HtmlTextWriter(writer);
html.RenderBeginTag(HtmlTextWriterTag.H1);
html.WriteEncodedText("Heading Here");
html.RenderEndTag();
html.WriteEncodedText(String.Format("Dear {0}", userName));
html.WriteBreak();
html.RenderBeginTag(HtmlTextWriterTag.P);
html.WriteEncodedText("First part of the email body goes here");
html.RenderEndTag();
html.Flush();
string htmlString = writer.ToString();
Run Code Online (Sandbox Code Playgroud)
对于包含样式属性创建的广泛HTML,HtmlTextWriter可能是最好的方法.然而,它可能有点笨拙使用和一些开发人员喜欢标记本身很容易阅读,但是经常HtmlTextWriter关于缩进的选择有点奇怪.
在这个例子中,您还可以非常有效地使用XmlTextWriter: -
writer = new StringWriter();
XmlTextWriter xml = new XmlTextWriter(writer);
xml.Formatting = Formatting.Indented;
xml.WriteElementString("h1", "Heading Here");
xml.WriteString(String.Format("Dear {0}", userName));
xml.WriteStartElement("br");
xml.WriteEndElement();
xml.WriteElementString("p", "First part of the email body goes here");
xml.Flush();
Run Code Online (Sandbox Code Playgroud)
Set*_*eth 15
更新答案:
SmtpClient本答案中使用的类的文档现在显示为"过时("SmtpClient及其类型网络设计不佳,我们强烈建议您使用https://github.com/jstedfast/MailKit和https:// github .com/jstedfast/MimeKit代替")'.
资料来源:https://www.infoq.com/news/2017/04/MailKit-MimeKit-Official
原答案:
使用MailDefinition类是错误的方法.是的,它很方便,但它也很原始,依赖于Web UI控件 - 这对于通常是服务器端任务的东西没有意义.
下面介绍的方法基于MSDN文档和Qureshi在CodeProject.com上的帖子.
注意:此示例从嵌入资源中提取HTML文件,图像和附件,但使用其他替代方法获取这些元素的流很好,例如硬编码字符串,本地文件等.
Stream htmlStream = null;
Stream imageStream = null;
Stream fileStream = null;
try
{
// Create the message.
var from = new MailAddress(FROM_EMAIL, FROM_NAME);
var to = new MailAddress(TO_EMAIL, TO_NAME);
var msg = new MailMessage(from, to);
msg.Subject = SUBJECT;
msg.SubjectEncoding = Encoding.UTF8;
// Get the HTML from an embedded resource.
var assembly = Assembly.GetExecutingAssembly();
htmlStream = assembly.GetManifestResourceStream(HTML_RESOURCE_PATH);
// Perform replacements on the HTML file (if you're using it as a template).
var reader = new StreamReader(htmlStream);
var body = reader
.ReadToEnd()
.Replace("%TEMPLATE_TOKEN1%", TOKEN1_VALUE)
.Replace("%TEMPLATE_TOKEN2%", TOKEN2_VALUE); // and so on...
// Create an alternate view and add it to the email.
var altView = AlternateView.CreateAlternateViewFromString(body, null, MediaTypeNames.Text.Html);
msg.AlternateViews.Add(altView);
// Get the image from an embedded resource. The <img> tag in the HTML is:
// <img src="pid:IMAGE.PNG">
imageStream = assembly.GetManifestResourceStream(IMAGE_RESOURCE_PATH);
var linkedImage = new LinkedResource(imageStream, "image/png");
linkedImage.ContentId = "IMAGE.PNG";
altView.LinkedResources.Add(linkedImage);
// Get the attachment from an embedded resource.
fileStream = assembly.GetManifestResourceStream(FILE_RESOURCE_PATH);
var file = new Attachment(fileStream, MediaTypeNames.Application.Pdf);
file.Name = "FILE.PDF";
msg.Attachments.Add(file);
// Send the email
var client = new SmtpClient(...);
client.Credentials = new NetworkCredential(...);
client.Send(msg);
}
finally
{
if (fileStream != null) fileStream.Dispose();
if (imageStream != null) imageStream.Dispose();
if (htmlStream != null) htmlStream.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
我使用dotLiquid来完成这个任务。
它需要一个模板,并用匿名对象的内容填充特殊标识符。
//define template
String templateSource = "<h1>{{Heading}}</h1>Dear {{UserName}},<br/><p>First part of the email body goes here");
Template bodyTemplate = Template.Parse(templateSource); // Parses and compiles the template source
//Create DTO for the renderer
var bodyDto = new {
Heading = "Heading Here",
UserName = userName
};
String bodyText = bodyTemplate.Render(Hash.FromAnonymousObject(bodyDto));
Run Code Online (Sandbox Code Playgroud)
它也适用于集合,请参阅一些在线示例。
小智 5
我建议使用某种模板。有各种不同的方法来解决这个问题,但本质上是在某个地方(在磁盘上,在数据库中等)保存电子邮件的模板,然后简单地将关键数据(即:收件人姓名等)插入模板中。
这更加灵活,因为这意味着您可以根据需要更改模板而无需更改代码。根据我的经验,您可能会收到来自最终用户的更改模板的请求。如果你想全力以赴,你可以包括一个模板编辑器。
作为 MailDefinition 的替代方案,请查看 RazorEngine https://github.com/Antaris/RazorEngine。
这看起来是一个更好的解决方案。
归因于...
例如
using RazorEngine;
using RazorEngine.Templating;
using System;
namespace RazorEngineTest
{
class Program
{
static void Main(string[] args)
{
string template =
@"<h1>Heading Here</h1>
Dear @Model.UserName,
<br />
<p>First part of the email body goes here</p>";
const string templateKey = "tpl";
// Better to compile once
Engine.Razor.AddTemplate(templateKey, template);
Engine.Razor.Compile(templateKey);
// Run is quicker than compile and run
string output = Engine.Razor.Run(
templateKey,
model: new
{
UserName = "Fred"
});
Console.WriteLine(output);
}
}
}
Run Code Online (Sandbox Code Playgroud)
哪个输出...
<h1>Heading Here</h1>
Dear Fred,
<br />
<p>First part of the email body goes here</p>
Run Code Online (Sandbox Code Playgroud)
前往这里
亲爱的弗雷德,
电子邮件正文的第一部分位于此处
| 归档时间: |
|
| 查看次数: |
207229 次 |
| 最近记录: |