C# 用C语言生成HTML邮件正文#
使用C#(用于通过System.Net.Mail发送)生成HTML电子邮件是否有比使用Stringbuilder执行以下操作更好的方法:C# 用C语言生成HTML邮件正文#,c#,html,email,C#,Html,Email,使用C#(用于通过System.Net.Mail发送)生成HTML电子邮件是否有比使用Stringbuilder执行以下操作更好的方法: string userName = "John Doe"; StringBuilder mailBody = new StringBuilder(); mailBody.AppendFormat("<h1>Heading Here</h1>"); mailBody.AppendFormat("Dear {0}," userName);
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>");
string userName=“John Doe”;
StringBuilder邮件体=新建StringBuilder();
附件格式(“此处标题”);
AppendFormat(“亲爱的{0}”,用户名);
mailBody.AppendFormat(“
”);
AppendFormat(“电子邮件正文的第一部分在这里””;
等等,等等?像这样发出手工构建的html可能是最好的方法,只要标记不太复杂。stringbuilder在经过大约三次串联后才开始在效率方面回报您,所以对于真正简单的东西,string+string就可以了
除此之外,您可以开始使用html控件(System.Web.UI.HtmlControl)并呈现它们,这样您有时可以继承它们并为复杂的条件布局创建自己的类别。使用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();
对于包含样式属性创建的广泛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();
您可以使用
这是您使用它的方式:
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());
MailDefinition md=newmaildefinition();
md.From=”test@domain.com";
md.IsBodyHtml=true;
md.Subject=“邮件定义测试”;
ListDictionary replacements=新建ListDictionary();
替换。添加(“{name}”,“Martin”);
替换。添加(“{country}”、“丹麦”);
string body=“你好{name}您来自{country}。”;
MailMessage msg=md.CreateMailMessage(“you@anywhere.com“,替换,正文,新系统.Web.UI.Control());
此外,我还写了一篇关于如何使用的博文。我建议使用某种模板。有各种不同的方法来实现这一点,但本质上是在某些地方(磁盘上、数据库中等)保存电子邮件模板,并简单地将关键数据(例如:收件人姓名等)插入模板中
这要灵活得多,因为这意味着您可以根据需要修改模板,而无需修改代码。根据我的经验,您可能会收到最终用户对模板的更改请求。如果你想一劳永逸,你可以包括一个模板编辑器。你可能想看看目前可用的一些模板框架。其中一些是MVC的衍生产品,但这不是必需的。是个不错的选择。如果您不想依赖完整的.NET Framework,还有一个库可以让您的代码看起来像:
string userName = "John Doe";
var mailBody = new HTML {
new H(1) {
"Heading Here"
},
new P {
string.Format("Dear {0},", userName),
new Br()
},
new P {
"First part of the email body goes here"
}
};
string htmlString = mailBody.Render();
它是开源的,你可以从
免责声明:我是此库的作者,编写此库的目的正是为了解决相同的问题-从应用程序发送HTML电子邮件。更新的答案: 此答案中使用的类
SmtpClient
,其文档现在显示为“过时(“SmtpClient及其类型网络设计不良,我们强烈建议您使用,而不是”)”
资料来源:
原始答案:
使用MailDefinition类是错误的方法。是的,它很方便,但它也很原始,并且依赖于web UI控件——这对于典型的服务器端任务来说没有意义
下面介绍的方法基于MSDN文档和
注意:本例从嵌入式资源中提取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();
}
Stream htmlStream=null;
Stream-imageStream=null;
Stream fileStream=null;
尝试
{
//创建消息。
var from=新邮件地址(来自电子邮件,来自姓名);
var to=新邮件地址(收件人电子邮件、收件人姓名);
var msg=新邮件消息(从,到);
msg.Subject=主语;
msg.SubjectEncoding=Encoding.UTF8;
//从嵌入式资源获取HTML。
var assembly=assembly.getExecutionGassembly();
htmlStream=assembly.GetManifestResourceStream(HTML\u资源\u路径);
//对HTML文件执行替换(如果将其用作模板)。
var reader=新的StreamReader(htmlStream);
变量body=读取器
.ReadToEnd()
.替换(“%TEMPLATE\u TOKEN1%”,TOKEN1\u值)
.Replace(“%TEMPLATE_TOKEN2%”,TOKEN2_VALUE);//依此类推。。。
//创建备用视图并将其添加到电子邮件中。
var altView=AlternateView.CreateAlternateViewFromString(body,null,MediaTypeNames.Text.Html);
msg.AlternateViews.Add(altView);
//从嵌入的资源获取映像
imageStream=assembly.GetManifestResourceStream(图像资源路径);
var linkedImage=新的LinkedResource(imageStream,“图像/png”);
linkedImage.ContentId=“IMAGE.PNG”;
altView.LinkedResources.Add(linkedImage);
//从嵌入式资源获取附件。
fileStream=assembly.GetManifestResourceStream(文件资源路径);
var file=新附件(fileStream,MediaTypeNames.Application.Pdf);
file.Name=“file.PDF”;
msg.Attachments.Add(文件);
//发送电子邮件
var客户端=新的SmtpClient(…);
client.Credentials=新的网络凭据(…);
client.Send(msg);
}
最后
{
如果(fileStream!=null)fileStream.Dispose();
如果(imageStream!=null)imageStream.Dispose();
如果(htmlStream!=null)htmlStream.Dispose();
}
作为MailDefinition的替代方案,请查看RazorEngine
这看起来是一个更好的解决方案
归因于
例如
使用RazorEngine;
使用RazorEngin
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);
}
}
}
<h1>Heading Here</h1>
Dear Fred,
<br />
<p>First part of the email body goes here</p>
//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));
Contact templateData = ...;
string html = Template
.FromFile("template.txt")
.DataFrom(templateData )
.Render();