System.Net.Mailを介して送信するために、C#でHTMLメールを生成するより良い方法は、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>");
などなど?
MailDefinition class を使用できます。
これがあなたの使い方です:
MailDefinition md = new MailDefinition();
md.From = "[email protected]";
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("[email protected]", replacements, body, new System.Web.UI.Control());
また、 MailDefinitionクラスを使用してテンプレートを使用してC#でHTML電子メール本文を生成する の方法に関するブログ記事を書きました。
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();
更新された回答:
この回答で使用されているSmtpClient
のドキュメントには、「Obsolete( "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のドキュメントと CodeProject.comのQureshiの投稿 に基づいています。
注:この例では、埋め込みリソースから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();
}
まさにこのタスクに 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));
コレクションでも機能します。 一部のオンライン例 を参照してください。
何らかのテンプレートを使用することをお勧めします。これにはさまざまな方法がありますが、基本的にはメールのテンプレートをどこかに(ディスク、データベースなど)保持し、キーデータ(IE:受信者名など)をテンプレートに挿入するだけです。
これは、コードを変更せずに必要に応じてテンプレートを変更できることを意味するため、はるかに柔軟です。私の経験では、エンドユーザーからテンプレートの変更要求を受け取る可能性があります。独り占めをしたい場合は、テンプレートエディタを含めることができます。
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);
}
}
}
どの出力...
<h1>Heading Here</h1>
Dear Fred,
<br />
<p>First part of the email body goes here</p>
ここに向かって
親愛なるフレッド、メール本文の最初の部分はここにあります
マークアップが複雑すぎない限り、このような手作りのhtmlを作成するのがおそらく最善の方法です。 stringbuilderは、約3つの連結の後に効率の面であなたに返済し始めるだけなので、本当に単純なものについてはstring + stringが行います。
それ以外は、htmlコントロール(System.Web.UI.HtmlControls)の使用を開始し、レンダリングすることができます。そうすれば、それらを継承して、複雑な条件付きレイアウトの独自のクラスを作成できます。
現時点で利用可能なテンプレートフレームワークの一部をご覧ください。それらのいくつかは、MVCの結果としてのスピンオフですが、それは必須ではありません。 Spark は良いものです。
完全な.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();
これはオープンソースであり、 http://sourceforge.net/projects/htmlplusplus/ からダウンロードできます。
免責事項:私はこのライブラリの作成者です。同じ問題を正確に解決するために書かれています-アプリケーションからHTMLメールを送信します。
同様の StackOverflow question があり、かなり包括的な回答が含まれています。個人的には、以前にASP.Netエンジンを使用してhtmlメールコンテンツを生成しようとしたテンプレートエンジンとして NVelocity を使用しています。 NVelocityは、非常に簡単に使用できますが、柔軟性が非常に高くなっています。テンプレートにASP.Net。aspxファイルを使用しても動作することがわかりましたが、予期しない副作用がありました。