ASP.NETでHTML /電子メールテンプレートを設定できますか?


97

かなりの数のメールを送信するサイトに取り組んでいます。ヘッダーとフッターの両方のテキスト、またはテンプレートを設定して、必要に応じてユーザーがこれらの電子メールを簡単に編集できるようにしたいと考えています。

HTMLをC#文字列リテラル内に埋め込むと、醜く、エスケープについて心配する必要があります。ヘッダーとフッターにフラットファイルを含めることは機能するかもしれませんが、それについて何かが正しくないと感じます。

どういう.ASPXわけか、ページをテンプレートとして使用するのが理想的であり、コードにそのページを提供するように伝え、メールに返されたHTMLを使用するだけです。

これを行う簡単で簡単な方法はありますか?この問題を解決するより良い方法はありますか?

更新:
標準の.aspxページをメールテンプレートとして使用できるようにする回答を追加しました。通常と同じようにすべての変数を置き換えたり、データバインディングを使用したりします。次に、ページの出力をキャプチャしてください。HTMLメールが届きました。

警告付きで更新!!!:
一部のaspxページでMailDefinitionクラスを使用していたのですが、実行中のサーバープロセス中にこのクラスを使用しようとすると失敗しました。MailDefinition.CreateMailMessage()メソッドは、常に何かを実行するわけではありませんが、参照するには有効なコントロールが必要なためです。このため、aspxページを使用する私のアプローチ、またはascxページを使用するMunのアプローチをお勧めします。


別の解決策を使用することですAlphaMailを作成し、C#と使用して電子メールを送信するComlangのテンプレート言語を。
ティモシーE.ヨハンソン

1
@JohnBubriski:次のように使用しnew System.Web.UI.Control()て、「警告付きの更新」で言及した制御の問題を回避しますmailDefinition.CreateMailMessage("somebody@fake.com", iDictionaryReplacements, new System.Web.UI.Control())
Theophilus、

ええ、私もそうしましたが、Razorの登場により、これはあまり良い考えではなくなりました。
ジョンブブリスキー

回答:


73

ここにはたくさんの回答がありますが、Razorを電子メールテンプレートで使用する方法についての素晴らしい記事を偶然見つけました。RazorはASP.NET MVC 3でプッシュされましたが、MVCはRazorを使用する必要はありません。これは電子メールテンプレートを実行するかなり洗練された処理です

「Razorの最も優れた点は、以前のバージョン(webforms)とは異なり、Web環境に関連付けられていないため、Webの外部で簡単にホストして、さまざまな目的のテンプレートエンジンとして使用できることです。」

RazorEngineによるHTMLメールの生成-パート01-はじめに

ASP.NET外でのRazorテンプレートの活用:それらはもはやHTMLだけではありません!

RazorEngineを使用したASP.NETのよりスマートな電子メールテンプレート

同様のStackoverflow QA

新しいRazorEngine APIを使用したテンプレート

MVCを使用しないRazorの使用

Razor View Engineをasp.netの外で使用することは可能ですか


1
+1。ただし、ユーザーがテンプレートを提供する場合は注意してください。ユーザーはテンプレートからC#コードを実行できるため、システムに必要以上のパワーを与えることができます。
AaronLS 2013年

セキュリティについてどう思いますか。このテンプレートエンジンを使用すると、ファイルシステム全体をフォーマットできる可能性があります。エンジンは好きですが、他のエンジンを見る必要があります。
der_chirurg 2013

55

また、コントロールを読み込んで、それを文字列にレンダリングし、それをHTML本文として設定することもできます。

// Declare stringbuilder to render control to
StringBuilder sb = new StringBuilder();

// Load the control
UserControl ctrl = (UserControl) LoadControl("~/Controls/UserControl.ascx");

// Do stuff with ctrl here

// Render the control into the stringbuilder
StringWriter sw = new StringWriter(sb);
Html32TextWriter htw = new Html32TextWriter(sw);
ctrl.RenderControl(htw);

// Get full body text
string body = sb.ToString();

その後、通常どおりメールを作成できます。

MailMessage message = new MailMessage();
message.From = new MailAddress("from@email.com", "from name");
message.Subject = "Email Subject";
message.Body = body;
message.BodyEncoding = Encoding.ASCII;
message.IsBodyHtml = true;

SmtpClient smtp = new SmtpClient("server");
smtp.Send(message);

ユーザーコントロールには、ヘッダーやフッターなどの他のコントロールを含めることができ、データバインディングなどの機能を利用することもできます。


私はどういうわけか初めてこの答えを逃しました...いいもの。私のソリューションに似ていますが、aspxの代わりにascxを使用します。コントロールではなく完全なページを提供するため、aspxの方が優れていると思いますが、それは私が考えていることです。
ジョンブブリスキー

はい、どちらのソリューションでも使用できます...それらは同じように機能します。このアプローチの利点の1つは、一貫性です。たとえば、同じコントロールを再利用して、注文の概要をユーザーに表示し、確認メールにまったく同じものを含めることができます。
ムン

マイナーポイントですが、最初のコードブロックでStringBuilderを宣言する行がありません。
Kirschstein、2009年

9
LoadControlはページ/コントロールのメソッドであるため、この例ではコードがどこにあるのかを説明していません。それはページですか?
Shrage Smilowi​​tz、2010年

@Mun、ユーザーコントロールをctrlと呼ばれる変数にロードし、コードで再び参照することはありません。これはどのように機能するはずですか?
マフィンマン

35

あなたはMailDefinitionクラスを試すことができます


4
これは基本的なメールには適していますが、複雑なものにはなりません。MailDefinitionクラスはデータバインディングをサポートしていません。それが実際に行う唯一のことは、文字列の置換を提供することです。ただし、メンバーシップアカウント作成ウィザードにも組み込まれています。
John Bubriski

4
MailDefinitionクラスは、テンプレート化されたコンテンツをレンダリングするためのコントロールを取得する必要があります。
結城

17

ユーザー名、製品名などのパラメーターを渡す場合は、オープンソーステンプレートエンジンNVelocityを使用して、最終的な電子メール/ HTMLを生成できます。

NVelocityテンプレート(MailTemplate.vm)の例:

A sample email template by <b>$name</b>.
<br />

Foreach example :
<br />    
#foreach ($item in $itemList)

[Date: $item.Date] Name: $item.Name, Value: $itemValue.Value
<br /><br />

#end

アプリケーションのMailTemplate.vmでメール本文を生成する:

VelocityContext context = new VelocityContext();
context.Put("name", "ScarletGarden");
context.Put("itemList", itemList);

StringWriter writer = new StringWriter();

Velocity.MergeTemplate("MailTemplate.vm", context, writer);

string mailBody = writer.GetStringBuilder().ToString();

結果のメール本文は次のとおりです。

ScarletGardenによるサンプル電子メールテンプレート 。

foreachの例:

[日付:2009年12月2日]名前:アイテム1、値:09

[日付:2009年2月21日]名前:アイテム4、値:52

[日付:2009年3月1日]名前:アイテム2、値:21

[日付:2009年3月23日]名前:アイテム6、値:24

テンプレートを編集するには、おそらくFCKEditorを使用して、テンプレートをファイルに保存できます。


7

Mail.dll電子メールコンポーネントには、電子メールテンプレートエンジンが含まれています。

構文の概要は次のとおりです。

<html>
<body>
Hi {FirstName} {LastName},

Here are your orders: 
{foreach Orders}
    Order '{Name}' sent to <strong>{Street}</strong>. 
{end}

</body>
</html>

そして、テンプレートをロードし、c#オブジェクトからデータを入力してメールを送信するコード:

Mail.Html(Template
              .FromFile("template.txt")
              .DataFrom(_contact)
              .Render())
    .Text("This is text version of the message.")
    .From(new MailBox("alice@mail.com", "Alice"))
    .To(new MailBox("bob@mail.com", "Bob"))
    .Subject("Your order")
    .UsingNewSmtp()
    .WithCredentials("alice@mail.com", "password")
    .Server("mail.com")
    .WithSSL()
    .Send();

メールテンプレートエンジンのブログ投稿で詳細を確認できます

または、Mail.dll電子メールコンポーネントをダウンロードして、試してみてください。

これは私が作成した商用製品であることに注意してください。


6

柔軟性が前提条件の1つである場合は、XSLTが適切な選択になる可能性があります。これは、.NETフレームワークによって完全にサポートされており、ユーザーがそれらのファイルを編集できるようにすることもできます。この記事(http://www.aspfree.com/c/a/XML/XSL-Transformations-using-ASP-NET/)は、最初に役立つかもしれません(msdnには詳細情報があります)。ScarletGardenで述べたように、NVelocityは別の良い選択ですが、私は「組み込み」の.NETフレームワークサポートとプラットフォームにとらわれないXSLTを好みます。


これまで考えたことはありませんでしたが、他の多くのメソッドを試した後IXmlSerializable、クラスにインターフェイスを追加することと組み合わせると、これがうまく機能することがわかりました。ほんの数行で、クラスにメールを送信できます。
cjbarth 2013年

ああ、XSLTの悪夢を見てきました。おそらく、私が使用した最も直感的でないプログラミング/マークアップ言語です。また、XSLTを最初にコーディングしてから1か月後に、他の人や自分自身のために維持することは不可能です。
PussInBoots 2014

5

次のようなこともできると思います。

.aspxページを作成し、OnLoadメソッドの最後に配置するか、手動で呼び出します。

    StringBuilder sb = new StringBuilder();
    StringWriter sw = new StringWriter(sb);
    HtmlTextWriter htmlTW = new HtmlTextWriter(sw);
    this.Render(htmlTW);

これに潜在的な問題があるかどうかはわかりませんが、うまくいくようです。これにより、テキスト置換のみをサポートするMailDefinitionクラスの代わりに、フル機能の.aspxページを使用できます。


MailDefinitionクラスは良い出発点ですが、少し初歩的なものです。このメソッドは、データバインディングやトレースなどの多くの機能をサポートする必要があります。これについての考え、または潜在的な落とし穴?
ジョンブブリスキー

すごい!何か問題がありましたか?
ジョンブブリスキー

メールテンプレートを変更する必要があるときに、ユーザーが.aspxファイルを編集できるようにしますか?私はそれを潜在的な問題と呼んでいます。
ブライアン

少なくとも、編集できる他のテンプレートと同じくらいのリスクはないと思います。確かに、彼らが自分のやっていることを知っていれば、害を及ぼす可能性がありますが、少なくともこの場合はそうではありません。これは、複雑な.aspxページではなく、プレースホルダーを含むテンプレートです。
ジョンブブリスキー

久しぶりですが、最終的な解決策を思い出しましたか?Page少なくともレンダリングに一般的な拡張メソッドを使用している場合、私はこの特定のアプローチをで機能させることができませんでした。したがって、私はに切り替えましたUserControl。以下の私の答えを見てください。これまでのところ、うまく機能しているようです...当時、どのように機能していたかを知りたいと思います。
InteXX 2014

4

確かに、htmlテンプレートを作成できます。テキストテンプレートもお勧めします。テンプレートでは、本文を配置する場所に[BODY]を置くだけで、テンプレートを読み込んで、本文を新しいコンテンツに置き換えることができます。.Nets Mail Classを使用してメールを送信できます。最初にメールを作成した後、すべての受信者へのメールの送信をループする必要があります。私にとっては魅力のように働きました。

using System.Net.Mail;

// Email content
string HTMLTemplatePath = @"path";
string TextTemplatePath = @"path";
string HTMLBody = "";
string TextBody = "";

HTMLBody = File.ReadAllText(HTMLTemplatePath);
TextBody = File.ReadAllText(TextTemplatePath);

HTMLBody = HTMLBody.Replace(["[BODY]", content);
TextBody = HTMLBody.Replace(["[BODY]", content);

// Create email code
MailMessage m = new MailMessage();

m.From = new MailAddress("address@gmail.com", "display name");
m.To.Add("address@gmail.com");
m.Subject = "subject";

AlternateView plain = AlternateView.CreateAlternateViewFromString(_EmailBody + text, new System.Net.Mime.ContentType("text/plain"));
AlternateView html = AlternateView.CreateAlternateViewFromString(_EmailBody + body, new System.Net.Mime.ContentType("text/html"));
mail.AlternateViews.Add(plain);
mail.AlternateViews.Add(html);

SmtpClient smtp = new SmtpClient("server");
smtp.Send(m);

StreamReaderのものを切り取って、File.ReadAllText(path)で置き換えることができます
John Sheehan

これは良いスタートですが、ヘッダーとフッターの機能のみを提供します。これは実際には体自体には役立ちません。
ジョンブブリスキー

ボディは、HTMLBodyフィールドとTextBodyフィールドに必要なボディコンテンツを入力するか、もちろんファイルに保存することもできます
Josh Mein

4

次に、より複雑な電子メールテンプレートにXSL変換を使用するもう1つの方法を示します。.NET アプリケーションからHTMLベースの電子メールを送信する


2
リンクが好きです。ありがとう!私の脳は変わり始め、私はそれをさらに一歩進め、XMLシリアル化可能なオブジェクト、またはWCFデータコントラクトをHTMLメール形式に変換するXSLTテンプレートを持っていることに気付きました。突然、私は実際のシリアライズ可能なクラスを通じて「強力なタイプの」電子メールテンプレートを手に入れました!
CodingWithSpike、2011

2

これを行うときは注意してください。SPAMフィルターはASP.netで生成されたhtmlをブロックしているようです。これは、ViewStateが原因であると考えられるため、これを行う場合は、生成されたHTMLがクリーンであることを確認してください。

個人的には、Asp.net MVCを使用して目的の結果を達成することを検討しています。またはNVelocityはこれでかなり良いです


1

どういうわけか、.ASPXページをテンプレートとして使用し、コードをそのページを提供するように伝え、返されたHTMLを電子メールに使用するだけです。

ASPXページをヒットして結果のHTMLを取得するWebRequestを簡単に作成できます。もう少し作業をすれば、おそらくWebRequestなしでそれを実行できます。PageParserとResponse.Filterを使用すると、ページを実行して出力をキャプチャできます。ただし、より洗練された方法がある場合もあります。


1

毎日膨大な数のメールを送信しなければならないプロジェクトの1つでも同様の要件があり、クライアントはさまざまな種類のメールのHTMLテンプレートを完全に制御したいと考えていました。

送信される電子メールの数が多いため、パフォーマンスが主な関心事でした。

私たちが思いついたのは、さまざまな種類の電子メール用のhtmlテンプレートマークアップ全体(実行時に実際のデータで置き換えられる[UserFirstName]、[UserLastName]などのプレースホルダーと共に)を保存するSQLサーバーの静的コンテンツです。

次に、このデータをasp.netキャッシュにロードしました。そのため、htmlテンプレートを繰り返し読み取ることはありません。ただし、実際に変更された場合のみです。

クライアントにWYSIWYGエディターを提供し、管理Webフォームを介してこれらのテンプレートを変更しました。更新が行われるたびに、asp.netキャッシュをリセットします。

次に、送信するすべてのメールがログに記録される、メールログ用の個別のテーブルを用意しました。このテーブルには、emailType、emailSent、numberOfTriesというフィールドがありました。

できるだけ早く送信する必要がある重要な電子メールの種類(新しいメンバーのサインアップ、パスワードを忘れたなど)について、5分ごとにジョブを実行しただけです。

重要度の低いメールタイプ(プロモーションメール、ニュースメールなど)に対して15分ごとに別のジョブを実行しました

この方法では、サーバーがノンストップメールを送信するのをブロックせず、メールをバッチで処理します。メールを送信したら、emailSentフィールドを1に設定します。


しかし、どのようにコレクションを処理しましたか?
Riri

1
私もこれを行い、うまくいきました。さらに、レポートが重要な場合は、過去に戻って送信された電子メールの記録を確認できます。
マークグローリー、

1

aspxおよびascxソリューションは現在のHttpContextを必要とするため、多くの作業なしに非同期で(たとえば、スレッドで)使用できないことに注意してください。


1

簡単な答えはMvcMailerだと思います。これは、お気に入りのビューエンジンを使用してメールを生成できるNuGetパッケージです。NuGetパッケージを参照してくださいここプロジェクトのドキュメントを

それが役に立てば幸い!


うーん、奇妙なことに、この答えはそれほど注目されていません。
PussInBoots 14

1

DotLiquidは別のオプションです。クラスモデルの値をとして指定し、{{ user.name }}実行時にそのクラスのデータとマークアップ付きのテンプレートを提供すると、値がマージされます。これは、さまざまな点でRazorテンプレートエンジンを使用するのと似ています。ループのようなより複雑なものや、ToUpperのようなさまざまな機能をサポートしています。良い点は、これらが「安全」であるため、テンプレートを作成するユーザーがシステムをクラッシュさせたり、かみそりのように安全でないコードを記述したりできないようにするためです。http//dotliquidmarkup.org/try-online


0

あなたはファイルの読み込み&書き込みにASPNETとそれに関連するユーザーの権限を許可することができるならば、あなたは簡単に標準でHTMLファイルを使用することができますString.Format()プレースホルダ({0}{1:C}これを達成するために、など)。

System.IO名前空間のクラスを使用して、単に文字列としてファイルを読み取ります。その文字列を取得したら、最初の引数としてに渡しString.Format()、パラメータを指定します。

その文字列を保持し、電子メールの本文として使用すれば、基本的には完了です。今日、これは数十の(確かに小規模な)サイトで行われており、問題は発生していません。

これは、(a)一度に何十億ものメールを送信していない場合、(b)各メールをパーソナライズしていない場合(そうでない場合、大量の文字列を消費する)、および(c )HTMLファイル自体は比較的小さいです。


0

セットを電子メールメッセージに設定しますIsBodyHtml = true

電子メールのコンテンツを含むオブジェクトを取得し、オブジェクトをシリアル化し、xml / xsltを使用してHTMLコンテンツを生成します。

AlternateViewsを実行する場合は、jmeinが異なるxsltテンプレートのみを使用してプレーンテキストコンテンツを作成するのと同じことを行います。

これの主な利点の1つは、レイアウトを変更したい場合に、xsltテンプレートを更新するだけです。


0

SubSonic(www.subsonicproject.com)を見てください。彼らはコードを生成するためにまさにこれを行っています-テンプレートは標準ASPXであり、c#を出力します。同じ方法をシナリオで再利用できます。


0

TemplateMachineのようなテンプレートライブラリを使用します。これにより、ほとんどの場合、メールテンプレートを通常のテキストと一緒に配置し、ルールを使用して必要に応じて値を挿入/置換できます。RubyのERBによく似ています。これにより、ASPXなどのようなものに過度に縛られることなく、メールコンテンツの生成を分離できます。これでコンテンツが生成されたら、メールで送信できます。


0

私はラージの答えが好きです。ListManagerのようなプログラムやDNNのようなフレームワークは同様のことを行い、技術者でないユーザーによる簡単な編集が必要な場合、SQLに保存されたHTMLを変更するWYSIWYGエディターは、最も簡単で簡単な方法であり、フッターとは別に編集ヘッダーに簡単に対応できます。など、トークンを使用して動的に値を挿入します。

上記の方法(または実際にはいずれか)を使用する場合に注意すべき点の1つは、エディターに挿入できるスタイルとタグのタイプについて厳格に注意することです。ブラウザーが厄介だと思う場合は、電子メールクライアントがどのように同じようにレンダリングするかがわかるまで待ってください...


0

Canavarの答えに似ていますが、Nvelocityの代わりに、常に「StringTemplate」を使用します。これは、構成ファイルからテンプレートをロードするか、File.ReadAllText()を使用して外部ファイルをロードし、値を設定します。

これはJavaプロジェクトですが、C#ポートはしっかりしており、いくつかのプロジェクトで使用しています(外部ファイルのテンプレートを使用して電子メールテンプレートを作成するために使用しただけです)。

選択肢は常に良いです。


0

WebClientクラスを使用する簡単な方法を次に示します

public static string GetHTMLBody(string url)
{
    string htmlBody;

    using (WebClient client = new WebClient ())
    {
        htmlBody = client.DownloadString(url);
    }

    return htmlBody;
}

次に、次のように呼び出します。

string url = "http://www.yourwebsite.com";
message.Body = GetHTMLBody(url);

もちろん、ほとんどのメールクライアント(Outlookなど)でWebページのスタイルを表示するには、CSSをインラインにする必要があります。電子メールに動的コンテンツ(顧客名など)が表示されている場合は、WebサイトでQueryStringsを使用してデータを入力することをお勧めします。(例:http://www.yourwebsite.com?CustomerName=Bob


端正ですが、他のほとんどの回答は、サイトにWebリクエストを返さずにこれを行うと思います。つまり、サイトでメール本文をホストする必要があります。
2012年

@Rup理解できますが、とにかく人々が電子メールの「Webバージョン」を見たいと思うことがよくあります。このソリューションは、そのシナリオに最適です。
ROFLwTIME

0

@bardevは優れたソリューションを提供しますが、残念ながらすべての場合に理想的ではありません。鉱山もその一つでした。

私はVS 2013でWebサイトでWebフォームを使用しています(私はWebサイトを二度と使用しないと確信しています-なんとPITA)。

Razorの提案を試しましたが、私のWebサイトは、IDEがMVCプロジェクトで提供する非常に重要なIntelliSenseを取得できませんでした。また、テンプレートにはデザイナーを使用することも好きです。これは、UserControlに最適な場所です。

かみそりで再びニクス。

そこで、代わりにこの小さなフレームワークを思いつきました(UserControlの場合は@ mun、Strong Typingの場合は@imatoriaへのヒント)。私が見ることができる唯一の潜在的な問題点は、.ASCXファイル名をクラス名と同期させるように注意する必要があることです。迷った場合は、ランタイムエラーが発生します。

FWIW:私のテストでは、少なくともRenderControl()呼び出しはページコントロールを好まないため、UserControlを使用しました。

ここにすべてを含めたと確信しています。何かを忘れた場合はお知らせください。

HTH

使用法:

Partial Class Purchase
  Inherits UserControl

  Private Sub SendReceipt()
    Dim oTemplate As MailTemplates.PurchaseReceipt

    oTemplate = MailTemplates.Templates.PurchaseReceipt(Me)
    oTemplate.Name = "James Bond"
    oTemplate.OrderTotal = 3500000
    oTemplate.OrderDescription = "Q-Stuff"
    oTemplate.InjectCss("PurchaseReceipt")

    Utils.SendMail("{0} <james.bond@mi6.co.uk>".ToFormat(oTemplate.Name), "Purchase Receipt", oTemplate.ToHtml)
  End Sub
End Class

基本クラス:

Namespace MailTemplates
  Public MustInherit Class BaseTemplate
    Inherits UserControl

    Public Shared Function GetTemplate(Caller As TemplateControl, Template As Type) As BaseTemplate
      Return Caller.LoadControl("~/MailTemplates/{0}.ascx".ToFormat(Template.Name))
    End Function



    Public Sub InjectCss(FileName As String)
      If Me.Styler IsNot Nothing Then
        Me.Styler.Controls.Add(New Controls.Styler(FileName))
      End If
    End Sub



    Private ReadOnly Property Styler As PlaceHolder
      Get
        If _Styler Is Nothing Then
          _Styler = Me.FindNestedControl(GetType(PlaceHolder))
        End If

        Return _Styler
      End Get
    End Property
    Private _Styler As PlaceHolder
  End Class
End Namespace

「ファクトリー」クラス:

Namespace MailTemplates
  Public Class Templates
    Public Shared ReadOnly Property PurchaseReceipt(Caller As TemplateControl) As PurchaseReceipt
      Get
        Return BaseTemplate.GetTemplate(Caller, GetType(PurchaseReceipt))
      End Get
    End Property
  End Class
End Namespace

テンプレートクラス:

Namespace MailTemplates
  Public MustInherit Class PurchaseReceipt
    Inherits BaseTemplate

    Public MustOverride WriteOnly Property Name As String
    Public MustOverride WriteOnly Property OrderTotal As Decimal
    Public MustOverride WriteOnly Property OrderDescription As String
  End Class
End Namespace

ASCXヘッダー:

<%@ Control Language="VB" ClassName="_Header" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<!--
  See https://www.campaignmonitor.com/blog/post/3317/ for discussion of DocType in HTML Email
-->

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title></title>
  <asp:PlaceHolder ID="plcStyler" runat="server"></asp:PlaceHolder>
</head>
<body>

ASCXフッター:

<%@ Control Language="VB" ClassName="_Footer" %>

</body>
</html>

ASCXテンプレート:

<%@ Control Language="VB" AutoEventWireup="false" CodeFile="PurchaseReceipt.ascx.vb" Inherits="PurchaseReceipt" %>

<%@ Register Src="_Header.ascx" TagName="Header" TagPrefix="uc" %>
<%@ Register Src="_Footer.ascx" TagName="Footer" TagPrefix="uc" %>

<uc:Header ID="ctlHeader" runat="server" />

  <p>Name: <asp:Label ID="lblName" runat="server"></asp:Label></p>
  <p>Order Total: <asp:Label ID="lblOrderTotal" runat="server"></asp:Label></p>
  <p>Order Description: <asp:Label ID="lblOrderDescription" runat="server"></asp:Label></p>

<uc:Footer ID="ctlFooter" runat="server" />

ASCXテンプレートCodeFile:

Partial Class PurchaseReceipt
  Inherits MailTemplates.PurchaseReceipt

  Public Overrides WriteOnly Property Name As String
    Set(Value As String)
      lblName.Text = Value
    End Set
  End Property



  Public Overrides WriteOnly Property OrderTotal As Decimal
    Set(Value As Boolean)
      lblOrderTotal.Text = Value
    End Set
  End Property



  Public Overrides WriteOnly Property OrderDescription As Decimal
    Set(Value As Boolean)
      lblOrderDescription.Text = Value
    End Set
  End Property
End Class

ヘルパー:

'
' FindNestedControl helpers based on tip by @andleer
' at http://stackoverflow.com/questions/619449/
'

Public Module Helpers
  <Extension>
  Public Function AllControls(Control As Control) As List(Of Control)
    Return Control.Controls.Flatten
  End Function



  <Extension>
  Public Function FindNestedControl(Control As Control, Id As String) As Control
    Return Control.Controls.Flatten(Function(C) C.ID = Id).SingleOrDefault
  End Function



  <Extension>
  Public Function FindNestedControl(Control As Control, Type As Type) As Control
    Return Control.Controls.Flatten(Function(C) C.GetType = Type).SingleOrDefault
  End Function



  <Extension>
  Public Function Flatten(Controls As ControlCollection) As List(Of Control)
    Flatten = New List(Of Control)

    Controls.Traverse(Sub(Control) Flatten.Add(Control))
  End Function


  <Extension>
  Public Function Flatten(Controls As ControlCollection, Predicate As Func(Of Control, Boolean)) As List(Of Control)
    Flatten = New List(Of Control)

    Controls.Traverse(Sub(Control)
                        If Predicate(Control) Then
                          Flatten.Add(Control)
                        End If
                      End Sub)
  End Function



  <Extension>
  Public Sub Traverse(Controls As ControlCollection, Action As Action(Of Control))
    Controls.Cast(Of Control).ToList.ForEach(Sub(Control As Control)
                                               Action(Control)

                                               If Control.HasControls Then
                                                 Control.Controls.Traverse(Action)
                                               End If
                                             End Sub)
  End Sub



  <Extension()>
  Public Function ToFormat(Template As String, ParamArray Values As Object()) As String
    Return String.Format(Template, Values)
  End Function



  <Extension()>
  Public Function ToHtml(Control As Control) As String
    Dim oSb As StringBuilder

    oSb = New StringBuilder

    Using oSw As New StringWriter(oSb)
      Using oTw As New HtmlTextWriter(oSw)
        Control.RenderControl(oTw)
        Return oSb.ToString
      End Using
    End Using
  End Function
End Module



Namespace Controls
  Public Class Styler
    Inherits LiteralControl

    Public Sub New(FileName As String)
      Dim _
        sFileName,
        sFilePath As String

      sFileName = Path.GetFileNameWithoutExtension(FileName)
      sFilePath = HttpContext.Current.Server.MapPath("~/Styles/{0}.css".ToFormat(sFileName))

      If File.Exists(sFilePath) Then
        Me.Text = "{0}<style type=""text/css"">{0}{1}</style>{0}".ToFormat(vbCrLf, File.ReadAllText(sFilePath))
      Else
        Me.Text = String.Empty
      End If
    End Sub
  End Class
End Namespace



Public Class Utils
  Public Shared Sub SendMail(Recipient As MailAddress, Subject As String, HtmlBody As String)
    Using oMessage As New MailMessage
      oMessage.To.Add(Recipient)
      oMessage.IsBodyHtml = True
      oMessage.Subject = Subject.Trim
      oMessage.Body = HtmlBody.Trim

      Using oClient As New SmtpClient
        oClient.Send(oMessage)
      End Using
    End Using
  End Sub
End Class

0

私が使用しているライブラリをミックスに投入するだけです:https : //github.com/lukencode/FluentEmail

RazorLightを使用してメールをレンダリングし、流暢なスタイルを使用してメールを作成し、箱から出して複数の送信者をサポートします。ASP.NET DIの拡張メソッドも付属しています。プレーンテキストとHTMLのサポートを備えた、使いやすく、設定はほとんどありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.