C#でPDFファイルをメール添付として送信する方法
ドキュメント配信の自動化は、ほぼすべての基幹業務.NETアプリケーションで必要となる要件です。 注文が行われると、請求書は数秒以内に顧客に届く必要があります。 レポートが夜間に作成される場合、関係者はオフィスに到着する前に受信トレイに届くことを期待します。最もシンプルで、最も広くサポートされている配信形式は、メールに添付されたPDFです。 このガイドでは、C# での完全なエンドツーエンドのワークフローについて説明します。IronPDF を使用してメモリ内にIronPDFドキュメントを生成し、MailKit または組み込みの System.Net.Mail 名前空間を使用して電子メールの添付ファイルとして送信します。ディスクに 1 バイトも書き込むことなく実行できます。
必要なパッケージをどのようにインストールしますか?
このワークフローは、PDF 生成ライブラリと電子メール送信ライブラリの 2 つのパッケージによって実行されます。 どちらも Visual Studio のパッケージ マネージャー コンソールまたは.NET CLI 経由でインストールします。
Install-Package IronPdf
dotnet add package IronPdf
Install-Package MailKit
dotnet add package MailKit
Install-Package IronPdf
dotnet add package IronPdf
Install-Package MailKit
dotnet add package MailKit
IronPDF は、HTML、CSS、 JavaScriptをピクセルパーフェクトな PDF ドキュメントに変換するChromium ベースのレンダリング エンジンを提供します。 これは Windows、Linux、macOS で実行されるため、同じコードがASP.NET Core Web API、バックグラウンド サービス、または Azure 関数で動作します。 MailKit は、Microsoft がすべての新しい.NET電子メール開発に推奨するライブラリであり、SMTP、IMAP、POP3、OAuth 2.0、および完全な MIME 構築をサポートしています。 MailKit のソースとドキュメントはGitHubで入手できます。
メモリ内に PDF ドキュメントを生成するにはどうすればよいでしょうか?
ChromePdfRenderer クラスは、 HTML から PDF への変換のエントリ ポイントです。 HTML 文字列を RenderHtmlAsPdf に渡すと、完全にメモリ内に存在する PdfDocument オブジェクトが返されます。 BinaryData プロパティを通じて生のバイトにアクセスします。このバイト配列は、電子メール添付ファイル API が期待するとおりです。
using IronPdf;
var renderer = new ChromePdfRenderer();
string htmlContent = """
<h1>Order Confirmation</h1>
<p>Thank you for your purchase.</p>
<table>
<tr><th>Item</th><th>Qty</th><th>Price</th></tr>
<tr><td>Widget A</td><td>2</td><td>$19.99</td></tr>
<tr><td>Widget B</td><td>1</td><td>$59.99</td></tr>
</table>
<p><strong>Order Total: $99.97</strong></p>
""";
PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
// pdf.BinaryData holds the complete PDF as a byte array
byte[] pdfBytes = pdf.BinaryData;
Console.WriteLine($"PDF generated: {pdfBytes.Length} bytes");
using IronPdf;
var renderer = new ChromePdfRenderer();
string htmlContent = """
<h1>Order Confirmation</h1>
<p>Thank you for your purchase.</p>
<table>
<tr><th>Item</th><th>Qty</th><th>Price</th></tr>
<tr><td>Widget A</td><td>2</td><td>$19.99</td></tr>
<tr><td>Widget B</td><td>1</td><td>$59.99</td></tr>
</table>
<p><strong>Order Total: $99.97</strong></p>
""";
PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
// pdf.BinaryData holds the complete PDF as a byte array
byte[] pdfBytes = pdf.BinaryData;
Console.WriteLine($"PDF generated: {pdfBytes.Length} bytes");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
Dim htmlContent As String = "
<h1>Order Confirmation</h1>
<p>Thank you for your purchase.</p>
<table>
<tr><th>Item</th><th>Qty</th><th>Price</th></tr>
<tr><td>Widget A</td><td>2</td><td>$19.99</td></tr>
<tr><td>Widget B</td><td>1</td><td>$59.99</td></tr>
</table>
<p><strong>Order Total: $99.97</strong></p>
"
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(htmlContent)
' pdf.BinaryData holds the complete PDF as a byte array
Dim pdfBytes As Byte() = pdf.BinaryData
Console.WriteLine($"PDF generated: {pdfBytes.Length} bytes")
RenderHtmlAsPdf メソッドは、Google Chrome を動かすのと同じ Chromium エンジンを使用して HTML を解析するため、テーブル、CSS グリッド、Flexbox、埋め込みフォントはすべてブラウザとまったく同じようにレンダリングされます。 結果は PdfDocument となり、その BinaryData プロパティはディスクの読み取りや書き込みを行わずに完全な PDF バイナリを返します。 外部画像やスタイルシートを取り込むドキュメントの場合は、オプションの BasePath パラメータを使用して、 IronPDF に相対リソース URL を解決する場所を指示します。これについては、HTML ファイルから PDF への変換方法に関するページで詳しく説明されています。
ページレイアウトとカスタムヘッダーの設定
PDF を添付する前に、余白、ヘッダー、またはフッターを設定することをお勧めします。 すべてのレイアウト オプションは、RenderingOptions プロパティにあります。
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.MarginTop = 15;
renderer.RenderingOptions.MarginBottom = 15;
renderer.RenderingOptions.MarginLeft = 12;
renderer.RenderingOptions.MarginRight = 12;
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:9pt;color:#666;text-align:right;'>Monthly Report</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:8pt;text-align:center;'>{page} of {total-pages}</div>"
};
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Monthly Summary</h1><p>See attached data.</p>");
byte[] pdfBytes = pdf.BinaryData;
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.MarginTop = 15;
renderer.RenderingOptions.MarginBottom = 15;
renderer.RenderingOptions.MarginLeft = 12;
renderer.RenderingOptions.MarginRight = 12;
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:9pt;color:#666;text-align:right;'>Monthly Report</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:8pt;text-align:center;'>{page} of {total-pages}</div>"
};
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Monthly Summary</h1><p>See attached data.</p>");
byte[] pdfBytes = pdf.BinaryData;
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.MarginTop = 15
renderer.RenderingOptions.MarginBottom = 15
renderer.RenderingOptions.MarginLeft = 12
renderer.RenderingOptions.MarginRight = 12
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='font-size:9pt;color:#666;text-align:right;'>Monthly Report</div>",
.DrawDividerLine = True
}
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='font-size:8pt;text-align:center;'>{page} of {total-pages}</div>"
}
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>Monthly Summary</h1><p>See attached data.</p>")
Dim pdfBytes As Byte() = pdf.BinaryData
余白の単位はミリメートルです。 {page} および {total-pages} トークンはレンダリング時に置き換えられます。HTML文字列から PDF への変換方法に関するページでは、レンダリングオプションの全セットについて説明しています。 生成されたドキュメントを添付する前に、透かしを追加したり、テキストや画像をスタンプしたりすることもできます。
MailKit を使用して PDF を電子メールに添付するにはどうすればよいですか?
MailKit は MIME メッセージ ツリーを直接構築し、コンテンツ タイプ、エンコード、添付ファイルのメタデータを完全に制御できます。 BodyBuilder ヘルパー クラスは、1 つ以上のファイル添付を含むテキストまたは HTML 本文の一般的なケースを簡素化します。
using IronPdf;
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
// Step 1 -- generate the PDF in memory
var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Monthly Report</h1><p>Generated automatically.</p>");
// Step 2 -- build the email message
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Reports Service", "reports@example.com"));
message.To.Add(new MailboxAddress("Alice Smith", "alice@example.com"));
message.Subject = "Your Monthly Report is Ready";
var builder = new BodyBuilder();
builder.TextBody = "Hello Alice,\n\nPlease find your monthly report attached.\n\nRegards,\nReports Service";
builder.HtmlBody = "<p>Hello Alice,</p><p>Please find your monthly report attached.</p>";
// Add the in-memory PDF as an attachment
builder.Attachments.Add("MonthlyReport.pdf", pdf.BinaryData, new ContentType("application", "pdf"));
message.Body = builder.ToMessageBody();
// Step 3 -- send via SMTP with TLS
using var client = new SmtpClient();
await client.ConnectAsync("smtp.example.com", 587, SecureSocketOptions.StartTls);
await client.AuthenticateAsync("username", "app-password");
await client.SendAsync(message);
await client.DisconnectAsync(true);
using IronPdf;
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
// Step 1 -- generate the PDF in memory
var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Monthly Report</h1><p>Generated automatically.</p>");
// Step 2 -- build the email message
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Reports Service", "reports@example.com"));
message.To.Add(new MailboxAddress("Alice Smith", "alice@example.com"));
message.Subject = "Your Monthly Report is Ready";
var builder = new BodyBuilder();
builder.TextBody = "Hello Alice,\n\nPlease find your monthly report attached.\n\nRegards,\nReports Service";
builder.HtmlBody = "<p>Hello Alice,</p><p>Please find your monthly report attached.</p>";
// Add the in-memory PDF as an attachment
builder.Attachments.Add("MonthlyReport.pdf", pdf.BinaryData, new ContentType("application", "pdf"));
message.Body = builder.ToMessageBody();
// Step 3 -- send via SMTP with TLS
using var client = new SmtpClient();
await client.ConnectAsync("smtp.example.com", 587, SecureSocketOptions.StartTls);
await client.AuthenticateAsync("username", "app-password");
await client.SendAsync(message);
await client.DisconnectAsync(true);
Imports IronPdf
Imports MailKit.Net.Smtp
Imports MailKit.Security
Imports MimeKit
' Step 1 -- generate the PDF in memory
Dim renderer As New ChromePdfRenderer()
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>Monthly Report</h1><p>Generated automatically.</p>")
' Step 2 -- build the email message
Dim message As New MimeMessage()
message.From.Add(New MailboxAddress("Reports Service", "reports@example.com"))
message.To.Add(New MailboxAddress("Alice Smith", "alice@example.com"))
message.Subject = "Your Monthly Report is Ready"
Dim builder As New BodyBuilder()
builder.TextBody = "Hello Alice," & vbCrLf & vbCrLf & "Please find your monthly report attached." & vbCrLf & vbCrLf & "Regards," & vbCrLf & "Reports Service"
builder.HtmlBody = "<p>Hello Alice,</p><p>Please find your monthly report attached.</p>"
' Add the in-memory PDF as an attachment
builder.Attachments.Add("MonthlyReport.pdf", pdf.BinaryData, New ContentType("application", "pdf"))
message.Body = builder.ToMessageBody()
' Step 3 -- send via SMTP with TLS
Using client As New SmtpClient()
Await client.ConnectAsync("smtp.example.com", 587, SecureSocketOptions.StartTls)
Await client.AuthenticateAsync("username", "app-password")
Await client.SendAsync(message)
Await client.DisconnectAsync(True)
End Using
builder.Attachments.Add は、受信者の電子メール クライアントに表示されるファイル名、pdf.BinaryData からの生のバイト配列、および MIME タイプを application/pdf として指定する ContentType インスタンスの 3 つの引数を受け入れます。 非同期 SMTP メソッドは、ネットワーク操作が完了する間、呼び出しスレッドを空のままにします。これは、数十の同時要求を処理するASP.NET Coreコントローラーでは重要です。
SecureSocketOptions.StartTls は、ポート 587 の SMTP サーバーと暗号化されたチャネルをネゴシエートします。Gmail の場合は、アカウント パスワードではなくアプリ パスワードを使用します。[Google アカウント セキュリティ] > [アプリ パスワード] でアプリ パスワードを生成し、AuthenticateAsync に渡します。 Microsoft 365 の場合、テナントで基本認証が無効になっている場合は、MailKit の SaslMechanismOAuth2 クラスを介して OAuth 2.0 認証を構成します。
複数の受信者に送信する
同じ電子メールに複数の人をコピーするには、SendAsync を呼び出す前に、Cc、または Bcc コレクションにアドレスを追加します。
message.To.Add(new MailboxAddress("Alice Smith", "alice@example.com"));
message.To.Add(new MailboxAddress("Bob Jones", "bob@example.com"));
message.Cc.Add(new MailboxAddress("Carol Manager", "carol@example.com"));
message.To.Add(new MailboxAddress("Alice Smith", "alice@example.com"));
message.To.Add(new MailboxAddress("Bob Jones", "bob@example.com"));
message.Cc.Add(new MailboxAddress("Carol Manager", "carol@example.com"));
message.To.Add(New MailboxAddress("Alice Smith", "alice@example.com"))
message.To.Add(New MailboxAddress("Bob Jones", "bob@example.com"))
message.Cc.Add(New MailboxAddress("Carol Manager", "carol@example.com"))
1 回の SendAsync 呼び出しでメッセージがすべてのアドレスに配信されます。 MailKit は RCPT TO コマンドを 1 つの SMTP セッションでバッチ処理するため、受信者が複数であってもパフォーマンスが低下することはありません。
System .NET.Mail を代替手段としてどのように使用しますか?
古い.NETバージョンを対象とするプロジェクト、またはサードパーティのNuGetパッケージの追加が許可されていないプロジェクトの場合、組み込みの System.Net.Mail 名前空間が基本的な SMTP 配信を処理します。 Microsoft は新規開発にはこれを推奨しなくなりましたが、追加の依存関係なしで一般的なユースケースをカバーします。
using IronPdf;
using System.Net;
using System.Net.Mail;
// Generate the PDF
var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Invoice #1001</h1><p>Amount due: $350.00</p>");
// Build the mail message
using var message = new MailMessage("invoices@example.com", "customer@example.com");
message.Subject = "Invoice #1001 Attached";
message.Body = "Your invoice is attached to this email. Please remit payment within 30 days.";
message.IsBodyHtml = false;
// Wrap the byte array in a MemoryStream for the Attachment constructor
var stream = new MemoryStream(pdf.BinaryData);
message.Attachments.Add(new Attachment(stream, "Invoice-1001.pdf", "application/pdf"));
// Send via SMTP
using var client = new SmtpClient("smtp.example.com", 587)
{
Credentials = new NetworkCredential("username", "password"),
EnableSsl = true
};
await client.SendMailAsync(message);
using IronPdf;
using System.Net;
using System.Net.Mail;
// Generate the PDF
var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Invoice #1001</h1><p>Amount due: $350.00</p>");
// Build the mail message
using var message = new MailMessage("invoices@example.com", "customer@example.com");
message.Subject = "Invoice #1001 Attached";
message.Body = "Your invoice is attached to this email. Please remit payment within 30 days.";
message.IsBodyHtml = false;
// Wrap the byte array in a MemoryStream for the Attachment constructor
var stream = new MemoryStream(pdf.BinaryData);
message.Attachments.Add(new Attachment(stream, "Invoice-1001.pdf", "application/pdf"));
// Send via SMTP
using var client = new SmtpClient("smtp.example.com", 587)
{
Credentials = new NetworkCredential("username", "password"),
EnableSsl = true
};
await client.SendMailAsync(message);
Imports IronPdf
Imports System.Net
Imports System.Net.Mail
Imports System.IO
' Generate the PDF
Dim renderer As New ChromePdfRenderer()
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>Invoice #1001</h1><p>Amount due: $350.00</p>")
' Build the mail message
Using message As New MailMessage("invoices@example.com", "customer@example.com")
message.Subject = "Invoice #1001 Attached"
message.Body = "Your invoice is attached to this email. Please remit payment within 30 days."
message.IsBodyHtml = False
' Wrap the byte array in a MemoryStream for the Attachment constructor
Dim stream As New MemoryStream(pdf.BinaryData)
message.Attachments.Add(New Attachment(stream, "Invoice-1001.pdf", "application/pdf"))
' Send via SMTP
Using client As New SmtpClient("smtp.example.com", 587)
client.Credentials = New NetworkCredential("username", "password")
client.EnableSsl = True
Await client.SendMailAsync(message)
End Using
End Using
MailKitとの主な違いは、usingステートメントで囲まれており、送信後にSMTP接続を破棄し、基になるストリームをフラッシュします。 MailMessage で using を省略すると、一部のランタイムで送信が完了する前に添付ファイル ストリームが破棄される可能性があります。
MailKit と System .NET.Mail の選択
| 特徴 | MailKit | System.Net.Mail |
|---|---|---|
| OAuth 2.0認証 | はい | なし |
| IMAP / POP3 サポート | はい | なし |
| 非同期ファーストAPI | はい | 部分的 |
| Microsoftの推奨事項 | 推奨 | 遺産 |
| 追加のNuGetパッケージ | 必須 | 不要 |
| 複雑なMIME構造 | フルサポート | 基本 |
特に SMTP サーバーで OAuth が必要な場合や、返信を読むために IMAP が必要な場合は、新しいプロジェクトには MailKit を選択してください。 コードベースがすでにこれに依存しており、移行コストが正当化されない場合は、System.Net.Mail を使用します。
このパターンを実際のビジネス ワークフローにどのように適用するのでしょうか?
メモリ内の PDF から電子メールへのパターンは、ほとんどのビジネス アプリケーションを駆動するドキュメント自動化シナリオに直接適用されます。
請求書自動化
電子商取引の注文処理担当者は、支払いが確定するとすぐに請求書 PDF を生成します。 OrderConfirmed イベントは、注文データから入力された Razor テンプレートの HTML 文字列を使用して RenderHtmlAsPdf を呼び出すメソッドをトリガーし、その結果を顧客の電子メール アドレスに送信します。 PDF はファイル システムに触れないため、クリーンアップするファイルが残らず、共有の一時ディレクトリで競合状態が発生することも、コンテナ化されたデプロイメントで権限の問題が発生することもありません。 Razorビューから HTML をレンダリングする方法の詳細については、 ASP.NET Core PDF 生成ガイドを参照してください。
スケジュールされたレポート配信
IHostedService でスケジュールされたバックグラウンド サービスは、毎週月曜日の 06:00 に週次分析サマリーを生成します。 データベースにクエリを実行し、HTMLレポート文字列を構築し、 IronPDFでレンダリングし、MailKitを使用して配布リストに送信します。パイプライン全体は非同期ワークフローとして実行されるため、SMTPハンドシェイク中にスレッドプールのスレッドを保持しません。 Azure でホストされるワークロードの場合、 Azure PDF ジェネレーター ガイドでは、 Azure App Service および Azure Functions 内にIronPDFをデプロイする方法が説明されています。
ASP.NET Coreでの領収書生成
ASP.NET Core の最小限の API またはコントローラー アクションでは、POST エンドポイントがチェックアウト ペイロードを受信し、領収書の PDF を生成し、電子メールを同時に送信しながら HTTP 200 を返します。 電子メール送信ロジックをバックグラウンドで実行し、HTTP 応答がすぐにクライアントに返されるようにします。
app.MapPost("/checkout", async (CheckoutRequest req, IEmailService emailService) =>
{
var renderer = new ChromePdfRenderer();
PdfDocument receipt = renderer.RenderHtmlAsPdf(BuildReceiptHtml(req));
// Fire and forget -- do not await so the HTTP response is immediate
_ = emailService.SendReceiptAsync(req.CustomerEmail, receipt.BinaryData);
return Results.Ok(new { message = "Order confirmed." });
});
app.MapPost("/checkout", async (CheckoutRequest req, IEmailService emailService) =>
{
var renderer = new ChromePdfRenderer();
PdfDocument receipt = renderer.RenderHtmlAsPdf(BuildReceiptHtml(req));
// Fire and forget -- do not await so the HTTP response is immediate
_ = emailService.SendReceiptAsync(req.CustomerEmail, receipt.BinaryData);
return Results.Ok(new { message = "Order confirmed." });
});
Imports System.Threading.Tasks
app.MapPost("/checkout", Async Function(req As CheckoutRequest, emailService As IEmailService) As Task(Of IResult)
Dim renderer As New ChromePdfRenderer()
Dim receipt As PdfDocument = renderer.RenderHtmlAsPdf(BuildReceiptHtml(req))
' Fire and forget -- do not await so the HTTP response is immediate
_ = emailService.SendReceiptAsync(req.CustomerEmail, receipt.BinaryData)
Return Results.Ok(New With {.message = "Order confirmed."})
End Function)
これにより、SMTP サーバーが低速の場合でも、API 応答時間が 100 ミリ秒未満に抑えられます。 emailService は、MailKit SmtpClient をラップするスコープ サービスまたは一時サービスとして登録されています。
エラーと再試行をどのように処理しますか?
ネットワーク操作が失敗します。 SMTP サーバーは一時的に利用できなくなり、認証トークンは期限切れとなり、添付ファイルのサイズ制限はプロバイダーによって異なります。 最初から電子メール送信パスに回復力を組み込みます。
MailKit の送信ロジックを try/catch でラップし、失敗を永続キューに記録して再試行できるようにします。
using IronPdf;
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
using Microsoft.Extensions.Logging;
async Task SendPdfEmailWithRetryAsync(
byte[] pdfBytes,
string recipientEmail,
string subject,
ILogger logger,
int maxAttempts = 3)
{
for (int attempt = 1; attempt <= maxAttempts; attempt++)
{
try
{
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Mailer", "mailer@example.com"));
message.To.Add(MailboxAddress.Parse(recipientEmail));
message.Subject = subject;
var builder = new BodyBuilder { TextBody = "Your document is attached." };
builder.Attachments.Add("document.pdf", pdfBytes, new ContentType("application", "pdf"));
message.Body = builder.ToMessageBody();
using var smtpClient = new SmtpClient();
await smtpClient.ConnectAsync("smtp.example.com", 587, SecureSocketOptions.StartTls);
await smtpClient.AuthenticateAsync("user", "pass");
await smtpClient.SendAsync(message);
await smtpClient.DisconnectAsync(true);
logger.LogInformation("Email sent to {Email} on attempt {Attempt}", recipientEmail, attempt);
return;
}
catch (Exception ex) when (attempt < maxAttempts)
{
logger.LogWarning(ex, "Send attempt {Attempt} failed. Retrying...", attempt);
await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)));
}
}
}
using IronPdf;
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
using Microsoft.Extensions.Logging;
async Task SendPdfEmailWithRetryAsync(
byte[] pdfBytes,
string recipientEmail,
string subject,
ILogger logger,
int maxAttempts = 3)
{
for (int attempt = 1; attempt <= maxAttempts; attempt++)
{
try
{
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Mailer", "mailer@example.com"));
message.To.Add(MailboxAddress.Parse(recipientEmail));
message.Subject = subject;
var builder = new BodyBuilder { TextBody = "Your document is attached." };
builder.Attachments.Add("document.pdf", pdfBytes, new ContentType("application", "pdf"));
message.Body = builder.ToMessageBody();
using var smtpClient = new SmtpClient();
await smtpClient.ConnectAsync("smtp.example.com", 587, SecureSocketOptions.StartTls);
await smtpClient.AuthenticateAsync("user", "pass");
await smtpClient.SendAsync(message);
await smtpClient.DisconnectAsync(true);
logger.LogInformation("Email sent to {Email} on attempt {Attempt}", recipientEmail, attempt);
return;
}
catch (Exception ex) when (attempt < maxAttempts)
{
logger.LogWarning(ex, "Send attempt {Attempt} failed. Retrying...", attempt);
await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)));
}
}
}
Imports IronPdf
Imports MailKit.Net.Smtp
Imports MailKit.Security
Imports MimeKit
Imports Microsoft.Extensions.Logging
Public Async Function SendPdfEmailWithRetryAsync(
pdfBytes As Byte(),
recipientEmail As String,
subject As String,
logger As ILogger,
Optional maxAttempts As Integer = 3) As Task
For attempt As Integer = 1 To maxAttempts
Try
Dim message = New MimeMessage()
message.From.Add(New MailboxAddress("Mailer", "mailer@example.com"))
message.To.Add(MailboxAddress.Parse(recipientEmail))
message.Subject = subject
Dim builder = New BodyBuilder With {
.TextBody = "Your document is attached."
}
builder.Attachments.Add("document.pdf", pdfBytes, New ContentType("application", "pdf"))
message.Body = builder.ToMessageBody()
Using smtpClient = New SmtpClient()
Await smtpClient.ConnectAsync("smtp.example.com", 587, SecureSocketOptions.StartTls)
Await smtpClient.AuthenticateAsync("user", "pass")
Await smtpClient.SendAsync(message)
Await smtpClient.DisconnectAsync(True)
End Using
logger.LogInformation("Email sent to {Email} on attempt {Attempt}", recipientEmail, attempt)
Return
Catch ex As Exception When attempt < maxAttempts
logger.LogWarning(ex, "Send attempt {Attempt} failed. Retrying...", attempt)
Await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)))
End Try
Next
End Function
指数バックオフ (最初の失敗から 2 秒後、2 回目の失敗から 4 秒後) により、過負荷の SMTP サーバーへの負荷が軽減されます。 運用アプリケーションでは、再試行ループをメッセージ キュー (Azure Service Bus、RabbitMQ、または AWS SQS) に置き換えて、アプリケーションの再起動後も障害が続くようにします。
IronPDF は、HTML コンテンツをレンダリングできない場合、PdfException もスローします。 エラー メッセージが具体的になるように、SMTP 例外とは別にキャッチします。
PdfDocument pdf;
try
{
pdf = renderer.RenderHtmlAsPdf(htmlContent);
}
catch (IronPdf.Exceptions.PdfException ex)
{
logger.LogError(ex, "PDF rendering failed");
throw;
}
PdfDocument pdf;
try
{
pdf = renderer.RenderHtmlAsPdf(htmlContent);
}
catch (IronPdf.Exceptions.PdfException ex)
{
logger.LogError(ex, "PDF rendering failed");
throw;
}
Imports IronPdf.Exceptions
Dim pdf As PdfDocument
Try
pdf = renderer.RenderHtmlAsPdf(htmlContent)
Catch ex As PdfException
logger.LogError(ex, "PDF rendering failed")
Throw
End Try
レンダリング エラーを配信エラーから分離すると、デバッグが高速化されます。 自動化されたドキュメント パイプラインでのエラー処理をより広範囲に検討するには、 5 ステップの PDF 生成ガイドで検証パターンを詳細に説明します。
添付ファイルのサイズをプロバイダーの制限内に抑えるにはどうすればよいでしょうか?
ほとんどの商用メールプロバイダーは、添付ファイルの最大サイズを制限しています。Gmailでは、個々の添付ファイルは25MBまでに制限されています。 Microsoft 365 の標準メールボックスのデフォルトは 20 MB です。 画像が埋め込まれた、スタイルが高度に設定された HTML レポートは、予期せずこれらの制限を超える可能性があります。
制限内に留まるために役立つ 3 つのテクニック:
レンダリング前に画像を圧縮します。インライン画像には、非圧縮のPNGではなく、圧縮されたJPEGまたはWebPを使用する必要があります。 600 dpi の PNG ロゴは PDF に数メガバイト追加される可能性があります。 同じ視覚的結果を得るには、品質 85% の JPEG は通常 200 KB 未満になります。
IronPDFの圧縮設定を使用してください。 PdfDocument.CompressImages方式は、レンダリング後に埋め込まれたビットマップの解像度を低下させます。 読む前に呼び出してください BinaryData:
pdf.CompressImages(60); // quality 0-100
byte[] compressedPdfBytes = pdf.BinaryData;
pdf.CompressImages(60); // quality 0-100
byte[] compressedPdfBytes = pdf.BinaryData;
pdf.CompressImages(60) ' quality 0-100
Dim compressedPdfBytes As Byte() = pdf.BinaryData
大きなレポートは複数のメールに分割してください。圧縮後でもプロバイダーの制限を超える場合は、セクションごとにPDFを1つ生成し、それぞれを別々のメールで送信してください。 PDF の分割と結合の方法に関するページでは、 CopyPages を使用して、PdfDocument をページ範囲で分割する方法を示します。
SMTP サイズ制限に関する外部参照: Gmail 添付ファイルの制限、 Microsoft 365 メッセージ サイズの制限。
次のステップは何ですか?
これで、 IronPDFを使用してメモリ内に PDF を生成し、MailKit または System.Net.Mail を使用して電子メールの添付ファイルとして送信するための実用的なテンプレートができました。 インメモリ アプローチにより、ディスクの読み取りと書き込みがなくなり、コンテナ化されたデプロイメントが簡素化され、一時ファイルのクリーンアップを必要とせずに高スループットのシナリオに拡張できます。
統合を深めるには:
- ヘッダー、フッター、ページ番号を含む複雑なドキュメント レイアウトを習得するには、HTML から PDF へのチュートリアルをお読みください。
- 余白、ページ サイズ、 JavaScript実行タイムアウトを制御するためのカスタム PDF レンダリング オプションを調べます。
- 生成された PDF に添付する前にデジタル署名を追加し、受信者に改ざん防止文書を提供します。
- 大規模なサーバーレス ドキュメント生成のために、 Azure Functions または App Serviceにデプロイします。
- 実稼働ライセンスを購入する前にIronPDF を無料で試して全機能をテストするか、展開価格のライセンス オプションを確認してください。
よくある質問
C# で、 生成 さ れた PDF を電子 メ ール添付で送信す る には ど う すれば よ いで し ょ う か。
IronPDFを使用すると、そのPDF作成機能を.NETのメール送信機能と統合することで、生成されたPDFファイルを電子メール添付ファイルとして送信できます。
.NETアプリケーションでPDFファイルを電子メールで送信する利点は何ですか?
.NETアプリケーションでPDFファイルを電子メールで送信すると、ドキュメント配信が自動化され、ビジネスワークフローが合理化され、顧客とのコミュニケーションが強化されます。
IronPDFはメール添付用のPDFの動的コンテンツを扱うことができますか?
はい、IronPDFは動的にPDFコンテンツを生成するため、カスタマイズされたPDFを電子メール添付ファイルとして送信する必要があるイベント駆動型アプリケーションに適しています。
IronPDFのメール送信メソッドでよく使われるパラメータは何ですか?
一般的なパラメータには、電子メールの件名、送信者情報、イベント駆動型アプリケーションの効率的な処理を保証するEventArgsが含まれます。
なぜIronPDFがドキュメント配信の自動化に適しているのですか?
IronPDFは信頼性の高いPDF作成を提供し、C#のメール送信機能と統合しているため、ドキュメントの配信を自動化するのに適しています。
IronPDFでPDFのメール送信をスケジュールできますか?
はい、IronPDFをスケジュールタスクに統合することで、指定した時間にPDFメールを自動送信し、ワークフローの効率を向上させることができます。
IronPDFは様々なデータソースからPDFを作成し、電子メールに添付することをサポートしていますか?
IronPDFは複数のデータソースからPDFを作成することをサポートしており、開発者が電子メール添付用の詳細なドキュメントを生成することができます。
IronPDFは顧客とのEメールコミュニケーションをどのように強化していますか?
IronPDFは詳細なPDFドキュメントを作成し、添付ファイルとして送信できるようにすることで、顧客とのEメールコミュニケーションのプロフェッショナリズムと明瞭性を高めます。
IronPDFを使用して請求書やレポートをPDF添付ファイルとして送信できますか?
はい、IronPDFはさまざまなビジネスニーズに対応する請求書、レポート、およびその他のドキュメントをPDF添付ファイルとして生成および送信するのに適しています。
IronPDF はビジネスワークフローの改善においてどのような役割を果たしますか?
IronPDFは、PDFドキュメントの作成と配布を可能にすることでビジネスワークフローを改善し、手動の介入とエラーを削減します。


