Comment envoyer un fichier PDF en tant que pièce jointe d'e-mail en C#
L'automatisation de la distribution de documents est une exigence qui se retrouve dans presque toutes les applications .NET métiers. Lorsqu'une commande est passée, la facture doit parvenir au client en quelques secondes. Lorsqu'un rapport est généré pendant la nuit, les parties prenantes s'attendent à le recevoir dans leur boîte de réception avant leur arrivée au bureau. Le format de diffusion le plus simple et le plus universellement pris en charge est le PDF envoyé en pièce jointe d'un courriel. Ce guide vous accompagne tout au long du flux de travail complet en C# : génération d'un document PDF en mémoire avec IronPDF , puis envoi en tant que pièce jointe d'un e-mail à l'aide de MailKit ou de l'espace de noms intégré System.Net.Mail, le tout sans écrire un seul octet sur le disque.
Comment installer les paquets requis ?
Ce flux de travail est alimenté par deux modules : une bibliothèque de génération de PDF et une bibliothèque d'envoi d'e-mails. Installez les deux via la console du gestionnaire de packages dans Visual Studio ou via l'interface de ligne de commande .NET .
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 intègre un moteur de rendu basé sur Chromium qui convertit le HTML, le CSS et le JavaScript en documents PDF d'une précision pixel parfaite. Il fonctionne sous Windows, Linux et macOS, ce qui signifie que le même code fonctionne dans une API Web ASP.NET Core , un service en arrière-plan ou une fonction Azure. MailKit est la bibliothèque recommandée par Microsoft pour tout nouveau développement de messagerie .NET ; elle prend en charge SMTP, IMAP, POP3, OAuth 2.0 et la construction MIME complète. Le code source et la documentation de MailKit sont disponibles sur GitHub.
Comment générer un document PDF en mémoire ?
La classe ChromePdfRenderer est le point d'entrée pour la conversion HTML vers PDF . Passez une chaîne HTML à RenderHtmlAsPdf et vous obtenez en retour un objet PdfDocument qui réside entièrement en mémoire. Accédez aux octets bruts via la propriété BinaryData -- ce tableau d'octets correspond exactement à ce qu'attendent les API de pièces jointes de courriel.
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")
La méthode RenderHtmlAsPdf analyse le HTML en utilisant le même moteur Chromium que celui qui alimente Google Chrome, de sorte que les tableaux, CSS Grid, Flexbox et les polices intégrées s'affichent exactement comme dans un navigateur. Le résultat est un PdfDocument dont la propriété BinaryData renvoie le binaire PDF complet sans aucune lecture ni écriture sur disque. Pour les documents qui importent des images ou des feuilles de style externes, utilisez le paramètre optionnel BasePath pour indiquer à IronPDF où résoudre les URL de ressources relatives -- ceci est traité en détail sur la page d'aide à la conversion de fichiers HTML en PDF .
Configuration de la mise en page et des en-têtes personnalisés
Avant de joindre le PDF, vous pouvez configurer les marges, les en-têtes ou les pieds de page. Toutes les options de mise en page se trouvent sur la propriété 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
Les marges sont exprimées en millimètres. Les jetons {page} et {total-pages} sont remplacés lors du rendu. La page d'instructions relative à la conversion de chaînes HTML en PDF détaille l'ensemble des options de rendu. Vous pouvez également ajouter des filigranes ou apposer du texte et des images sur le document généré avant de le joindre.
Comment joindre un PDF à un e-mail avec MailKit ?
MailKit construit directement une arborescence de messages MIME, vous offrant un contrôle total sur le type de contenu, l'encodage et les métadonnées des pièces jointes. La classe d'assistance BodyBuilder simplifie le cas courant d'un corps de texte ou HTML avec une ou plusieurs pièces jointes.
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 accepte trois arguments : le nom de fichier que le destinataire voit dans son client de messagerie, le tableau d'octets brut de pdf.BinaryData et une instance de ContentType spécifiant le type MIME comme application/pdf. Les méthodes SMTP asynchrones permettent de libérer le thread appelant pendant la durée de l'opération réseau, ce qui est essentiel dans les contrôleurs ASP.NET Core qui gèrent des dizaines de requêtes simultanées.
SecureSocketOptions.StartTls négocie un canal chiffré avec le serveur SMTP sur le port 587. Pour Gmail, utilisez un mot de passe d'application plutôt que votre mot de passe de compte : générez-en un sous Sécurité du compte Google > Mots de passe d'application, puis transmettez-le à AuthenticateAsync. Pour Microsoft 365, configurez l'authentification OAuth 2.0 via la classe SaslMechanismOAuth2 de MailKit si votre locataire a désactivé l'authentification de base.
Envoi à plusieurs destinataires
Pour mettre plusieurs personnes en copie du même courriel, ajoutez les adresses aux collections To, Cc ou Bcc avant d'appeler SendAsync :
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"))
Un seul appel SendAsync délivre le message à toutes les adresses. MailKit regroupe les commandes RCPT TO dans une seule session SMTP, il n'y a donc aucune perte de performance pour plusieurs destinataires.
Comment utiliser System.Net.Mail comme alternative ?
Pour les projets ciblant des versions .NET plus anciennes ou les projets où l'ajout d'un package NuGet tiers n'est pas autorisé, l'espace de noms intégré System.Net.Mail gère la livraison SMTP de base. Microsoft ne le recommande plus pour les nouveaux développements, mais il couvre les cas d'utilisation courants sans dépendances supplémentaires.
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
La principale différence par rapport à MailKit est que System.Net.Mail.Attachment n'accepte pas directement un tableau d'octets ; vous devez d'abord l'encapsuler dans un pdf.BinaryData. Les instructions MailMessage et SmtpClient sont toutes deux encapsulées dans des instructions using, qui ferment la connexion SMTP et vident le flux sous-jacent après l'envoi. Si vous omettez le using sur MailMessage, le flux de pièces jointes peut être supprimé avant que l'envoi ne soit terminé sur certains environnements d'exécution.
Choisir entre MailKit et System.Net.Mail
| Caractéristique | MailKit | System.Net.Mail |
|---|---|---|
| Authentification OAuth 2.0 | Oui | Non |
| Prise en charge IMAP/POP3 | Oui | Non |
| API asynchrone | Oui | Partiel |
| Recommandation de Microsoft | Recommandé | Héritage |
| Package NuGet supplémentaire | Requis | Non requis |
| Construction MIME complexe | Prise en charge complète | Basique |
Choisissez MailKit pour tout nouveau projet, surtout si le serveur SMTP requiert OAuth ou si vous avez besoin d'IMAP pour lire les réponses. Utilisez System.Net.Mail lorsque le code source en dépend déjà et que le coût de la migration n'est pas justifié.
Comment appliquer ce modèle aux flux de travail réels d'une entreprise ?
Le modèle de conversion PDF en e-mail en mémoire s'applique directement aux scénarios d'automatisation documentaire qui sous-tendent la plupart des applications métier.
Automatisation des factures
Un système de gestion des commandes de commerce électronique génère une facture au format PDF immédiatement après la réception du paiement. L'événement OrderConfirmed déclenche une méthode qui appelle RenderHtmlAsPdf avec une chaîne HTML Razor remplie à partir des données de commande, puis envoie le résultat à l'adresse e-mail du client. Comme le PDF n'accède jamais au système de fichiers, il n'y a pas de fichiers résiduels à nettoyer, pas de risques de concurrence sur un répertoire temporaire partagé et aucun problème d'autorisation dans les déploiements conteneurisés. Pour en savoir plus sur le rendu HTML à partir des vues Razor , consultez le guide de génération de PDF ASP.NET Core .
Distribution des rapports programmés
Un service en arrière-plan programmé avec IHostedService génère un résumé analytique hebdomadaire à 06h00 tous les lundis. Il interroge la base de données, génère un rapport HTML, le convertit en PDF avec IronPDF et l'envoie à une liste de diffusion via MailKit. L'ensemble du processus s'exécute de manière asynchrone, évitant ainsi la mobilisation d'un thread pendant la négociation SMTP. Pour les charges de travail hébergées sur Azure, le guide du générateur PDF Azure explique comment déployer IronPDF dans Azure App Service et Azure Functions.
Génération de reçus dans ASP.NET Core
Dans une API minimale ou une action de contrôleur ASP.NET Core , un point de terminaison POST reçoit une charge utile de paiement, génère un PDF de reçu et renvoie un code HTTP 200 tout en déclenchant simultanément l'envoi de l'e-mail. Gardez la logique d'envoi d'e-mails en arrière-plan Task afin que la réponse HTTP soit renvoyée immédiatement au client :
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)
Cela permet de maintenir le temps de réponse de l'API en dessous de 100 ms même lorsque le serveur SMTP est lent. Le emailService est enregistré en tant que service limité ou transitoire qui encapsule le MailKit SmtpClient.
Comment gérez-vous les erreurs et les nouvelles tentatives ?
Les opérations réseau échouent. Les serveurs SMTP sont temporairement indisponibles, les jetons d'authentification expirent et les limites de taille des pièces jointes varient selon le fournisseur. Intégrez la résilience dans le processus d'envoi des e-mails dès le départ.
Encapsulez la logique d'envoi de MailKit dans un bloc try/catch et consignez les échecs dans une file d'attente persistante afin de pouvoir les réessayer :
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
Le délai exponentiel (2 secondes après la première panne, 4 après la seconde) empêche de surcharger un serveur SMTP. Dans les applications de production, remplacez la boucle de nouvelle tentative par une file d'attente de messages (Azure Service Bus, RabbitMQ ou AWS SQS) afin que les échecs persistent après les redémarrages de l'application.
IronPDF génère également une erreur PdfException si le contenu HTML ne peut pas être rendu. Interrompez cette situation séparément des exceptions SMTP afin que le message d'erreur soit spécifique :
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
Distinguer les erreurs de rendu des erreurs de diffusion permet un débogage plus rapide. Pour une analyse plus approfondie de la gestion des erreurs dans les pipelines de documents automatisés, le guide de génération de PDF en 5 étapes couvre en détail les modèles de validation.
Comment faire pour que la taille des pièces jointes reste inférieure aux limites imposées par le fournisseur ?
La plupart des fournisseurs de messagerie commerciale imposent une taille maximale pour les pièces jointes. Gmail limite les pièces jointes individuelles à 25 Mo ; Microsoft 365 attribue par défaut une taille de 20 Mo aux boîtes aux lettres standard. Un rapport HTML fortement stylisé avec des images intégrées peut dépasser ces limites de manière inattendue.
Trois techniques permettent de rester dans les limites :
Compressez les images avant le rendu. Les images intégrées doivent utiliser le format JPEG ou WebP compressé plutôt que le format PNG non compressé. Un logo PNG de 600 dpi peut ajouter plusieurs mégaoctets au PDF ; Un fichier JPEG de qualité 85 % pèse généralement moins de 200 Ko pour un résultat visuel identique.
Utilisez les paramètres de compression d'IronPDF. La méthode PdfDocument.CompressImages réduit la résolution des bitmaps intégrés après le rendu. Appelez avant de lire 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
Fractionnez les rapports volumineux en plusieurs e-mails. Si un rapport dépasse la limite de taille autorisée par votre fournisseur, même après compression, générez un PDF par section et envoyez-les séparément. La page d'instructions sur la division et la fusion de PDF montre comment diviser un PdfDocument par plage de pages en utilisant CopyPages.
Références externes concernant les limites de taille SMTP : limites des pièces jointes Gmail , limites de taille des messages Microsoft 365 .
Quelles sont vos prochaines étapes ?
Vous disposez maintenant d'un modèle fonctionnel pour générer un PDF en mémoire avec IronPDF et l'envoyer en pièce jointe d'un e-mail en utilisant soit MailKit, soit System.Net.Mail. L'approche en mémoire élimine les lectures et écritures sur disque, simplifie les déploiements conteneurisés et s'adapte aux scénarios à haut débit sans nécessiter de nettoyage des fichiers temporaires.
Pour approfondir l'intégration :
- Consultez le tutoriel HTML vers PDF pour maîtriser la mise en page complexe des documents avec en-têtes, pieds de page et numérotation des pages.
- Explorez les options de rendu PDF personnalisées pour contrôler les marges, la taille de la page et le délai d'exécution JavaScript .
- Ajoutez une signature numérique au PDF généré avant de le joindre, afin de fournir aux destinataires des documents inviolables.
- Déploiement sur Azure Functions ou App Service pour la génération de documents sans serveur à grande échelle.
- Essayez IronPDF gratuitement pour tester l'ensemble de ses fonctionnalités avant de souscrire à une licence de production, ou consultez les options de licence pour connaître les tarifs de déploiement.
Questions Fréquemment Posées
Comment puis-je envoyer un PDF généré en tant que pièce jointe à un courriel en C# ?
En using IronPDF, vous pouvez envoyer des fichiers PDF générés en tant que pièces jointes par e-mail en intégrant ses capacités de création de PDF avec les fonctionnalités d'envoi d'e-mails de .NET.
Quels sont les avantages de l'envoi de fichiers PDF par courrier électronique dans les applications .NET ?
L'envoi de fichiers PDF par courrier électronique dans les applications .NET permet d'automatiser la livraison de documents, de rationaliser les flux de travail des entreprises et d'améliorer la communication avec les clients.
IronPDF peut-il gérer le contenu dynamique des PDF pour les pièces jointes aux courriels ?
Oui, IronPDF génère dynamiquement du contenu PDF, ce qui le rend adapté aux applications déclenchées par des événements nécessitant l'envoi de PDF personnalisés en tant que pièces jointes par e-mail.
Quels sont les paramètres couramment utilisés dans les méthodes d'envoi de courriels avec IronPDF ?
Les paramètres courants comprennent l'objet de l'e-mail, les informations relatives à l'expéditeur et les EventArgs, qui garantissent un traitement efficace dans les applications pilotées par les événements.
Pourquoi IronPDF est-il adapté à l'automatisation de la diffusion de documents ?
IronPDF est adapté à l'automatisation de la livraison de documents car il offre une création de PDF fiable et s'intègre avec les capacités d'envoi d'e-mails en C#.
Est-il possible de programmer l'envoi de PDF par email avec IronPDF ?
Oui, IronPDF peut être intégré à des tâches planifiées pour automatiser l'envoi de courriels PDF à des moments précis, améliorant ainsi l'efficacité du flux de travail.
IronPDF prend-il en charge la création de PDF à partir de diverses sources de données pour les pièces jointes aux courriels ?
IronPDF prend en charge la création de PDF à partir de plusieurs sources de données, permettant aux développeurs de générer des documents détaillés pour des pièces jointes d'e-mails.
Comment IronPDF améliore-t-il la communication par courriel avec ses clients ?
En permettant la génération et l'envoi de documents PDF détaillés en pièces jointes, IronPDF renforce le professionnalisme et la clarté des communications par courriel avec les clients.
IronPDF peut-il être utilisé pour envoyer des factures et des rapports en tant que pièces jointes PDF ?
Oui, IronPDF est bien adapté pour générer et envoyer des factures, des rapports et d'autres documents en tant que pièces jointes PDF, répondant à divers besoins professionnels.
Quel rôle joue IronPDF dans l'amélioration des flux de travail des entreprises ?
IronPDF améliore les flux de travail d'entreprise en permettant la création et la distribution de documents PDF, réduisant l'intervention manuelle et les erreurs.



