.Net MailMessage-Objekt als EML-Datei speichern: Unterschied zwischen den Versionen
Deko (Diskussion | Beiträge) |
imported>TechCorner-Redaktion Überarbeitung: MailKit/MimeKit, Fix PickupDirectoryLocation, Kategorie Softwareentwicklung, Stand Oktober 2026 |
||
| (3 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
===''' | {{Steckbrief | ||
E- | | gilt_fuer = .NET 8/10, .NET Framework 4.8.x; System.Net.Mail und MailKit/MimeKit 4.x | ||
| bereich = Softwareentwicklung | |||
| dauer = ca. 15 Minuten | |||
| rechte = Schreibrechte im Ablageordner der Anwendung | |||
| stand = Oktober 2026 | |||
}} | |||
'''Ein .NET-MailMessage-Objekt als EML-Datei speichern''' sichert E-Mails, die Ihre Anwendung wegen eines Fehlers nicht versenden konnte – samt Kopfzeilen und Anhängen. Statt nur einer Fehlermeldung im Log liegt die Original-Mail vor, lässt sich in Outlook oder Thunderbird öffnen und später erneut versenden. | |||
[[Datei:NET-MailMessage-EML.png|thumb|center|750px|Nicht versendete E-Mails als EML-Datei sichern: mit MailKit über WriteToAsync oder mit System.Net.Mail über ein Pickup-Verzeichnis mit absolutem Pfad.]] | |||
< | == Problem == | ||
using | * Von einem Webserver oder Dienst erzeugte E-Mails scheitern beim Versand (SMTP-Server nicht erreichbar, Authentifizierung, Zeitüberschreitung). | ||
using | * Im Log steht nur die Exception – die eigentliche Mail ist verloren und der Fehler schwer nachzuvollziehen. | ||
using | |||
== Lösung == | |||
=== Variante 1: MailKit/MimeKit (empfohlen) === | |||
Microsoft empfiehlt <code>System.Net.Mail.SmtpClient</code> nicht mehr für neue Entwicklungen, weil er moderne Protokolle und Anmeldeverfahren (z. B. OAuth 2.0) nicht unterstützt. Der Standard ist '''MailKit''' mit dem Nachrichtenmodell '''MimeKit'''. Dort ist das Speichern als EML ein Einzeiler: | |||
<syntaxhighlight lang="bash"> | |||
dotnet add package MailKit | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="csharp"> | |||
using MailKit.Net.Smtp; | |||
using MailKit.Security; | |||
using MimeKit; | |||
var message = new MimeMessage(); | |||
message.From.Add(MailboxAddress.Parse("shop@example.com")); | |||
message.To.Add(MailboxAddress.Parse("kunde@example.com")); | |||
message.Subject = "Ihre Bestellung"; | |||
message.Body = new TextPart("plain") { Text = "Vielen Dank für Ihre Bestellung." }; | |||
try | |||
{ | |||
using var smtp = new SmtpClient(); | |||
await smtp.ConnectAsync("smtp.example.com", 587, SecureSocketOptions.StartTls); | |||
await smtp.AuthenticateAsync("benutzer", "passwort"); | |||
await smtp.SendAsync(message); | |||
await smtp.DisconnectAsync(true); | |||
} | |||
catch (Exception ex) | |||
{ | { | ||
var dir = Path.Combine(AppContext.BaseDirectory, "mail-fehler"); | |||
Directory.CreateDirectory(dir); | |||
var file = Path.Combine(dir, $"{DateTime.UtcNow:yyyyMMdd-HHmmss}-{Guid.NewGuid():N}.eml"); | |||
await message.WriteToAsync(file); // komplette Mail als EML sichern | |||
logger.LogError(ex, "Mailversand fehlgeschlagen, gesichert unter {File}", file); | |||
} | } | ||
</ | </syntaxhighlight> | ||
Eine gesicherte Mail lässt sich später mit <code>MimeMessage.Load(file)</code> wieder einlesen und erneut versenden. | |||
// ... | === Variante 2: System.Net.Mail (Bestandscode) === | ||
Für bestehende Anwendungen mit <code>MailMessage</code> funktioniert der Trick über das Pickup-Verzeichnis: Ein zweiter <code>SmtpClient</code> „versendet“ die Mail als Datei in einen Ordner. | |||
<syntaxhighlight lang="csharp"> | |||
using System.Net.Mail; | |||
public static class MailMessageExtensions | |||
{ | |||
/// <summary>Speichert eine MailMessage als EML-Datei im angegebenen Ordner.</summary> | |||
public static void Archive(this MailMessage message, string directory) | |||
{ | |||
Directory.CreateDirectory(directory); | |||
using var diskClient = new SmtpClient | |||
{ | |||
DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory, | |||
PickupDirectoryLocation = directory | |||
}; | |||
diskClient.Send(message); | |||
} | |||
} | |||
</syntaxhighlight> | |||
Verwendung im Fehlerfall: | |||
<syntaxhighlight lang="csharp"> | |||
try | try | ||
{ | { | ||
smtpClient.Send(message); | |||
} | } | ||
catch ( | catch (SmtpException ex) | ||
{ | { | ||
message.Archive(Path.Combine(Path.GetTempPath(), "mail-fehler")); | |||
logger.LogError(ex, "Mailversand fehlgeschlagen"); | |||
} | } | ||
</ | </syntaxhighlight> | ||
{{Warnung|<code>PickupDirectoryLocation</code> erwartet einen '''absoluten Pfad''' zu einem '''existierenden''' Ordner. Umgebungsvariablen wie <code>%TEMP%</code> werden nicht aufgelöst – deshalb <code>Path.GetTempPath()</code> bzw. <code>Directory.CreateDirectory</code> verwenden. Der Dateiname wird automatisch als GUID vergeben.}} | |||
=== ''' | == Hinweise == | ||
* '''Datenschutz:''' EML-Dateien enthalten personenbezogene Daten. Ablageordner nur für das Dienstkonto lesbar machen, nicht unter <code>wwwroot</code> ablegen und alte Dateien automatisch löschen ([[DSGVO]]). | |||
[ | * '''Wiederholung:''' Für produktive Systeme eignet sich ein Hintergrunddienst, der den Ordner regelmäßig abarbeitet und gesicherte Mails erneut versendet. | ||
* '''Microsoft 365:''' Der SMTP-Versand mit Basic Authentication wird bei Exchange Online abgeschaltet. MailKit unterstützt OAuth 2.0 bzw. den Versand über Microsoft Graph. | |||
* Bei Entwicklung und Modernisierung von .NET-Anwendungen unterstützt Sie die [https://www.max-it.de/development/individuelle-softwareentwicklung/ individuelle Softwareentwicklung von m.a.x. it]. | |||
== Siehe auch == | |||
* [[SMTP]] | |||
* [[WCF Rest-Service]] | |||
* [[DSGVO]] | |||
== | == Links und Quellen == | ||
. | * [https://learn.microsoft.com/de-de/dotnet/api/system.net.mail.smtpclient Microsoft Learn: SmtpClient-Klasse (mit Empfehlung für MailKit)] | ||
* [https://www.max-it.de/development/individuelle-softwareentwicklung/ Individuelle Softwareentwicklung von m.a.x. it] | |||
{{Uebermax}} | |||
[[Kategorie:Softwareentwicklung]] | |||
Aktuelle Version vom 14. Oktober 2026, 00:00 Uhr
Auf einen Blick
| Gilt für | .NET 8/10, .NET Framework 4.8.x; System.Net.Mail und MailKit/MimeKit 4.x |
|---|---|
| Bereich | Softwareentwicklung |
| Dauer | ca. 15 Minuten |
| Rechte | Schreibrechte im Ablageordner der Anwendung |
| Stand | Oktober 2026 |
Ein .NET-MailMessage-Objekt als EML-Datei speichern sichert E-Mails, die Ihre Anwendung wegen eines Fehlers nicht versenden konnte – samt Kopfzeilen und Anhängen. Statt nur einer Fehlermeldung im Log liegt die Original-Mail vor, lässt sich in Outlook oder Thunderbird öffnen und später erneut versenden.

Problem
- Von einem Webserver oder Dienst erzeugte E-Mails scheitern beim Versand (SMTP-Server nicht erreichbar, Authentifizierung, Zeitüberschreitung).
- Im Log steht nur die Exception – die eigentliche Mail ist verloren und der Fehler schwer nachzuvollziehen.
Lösung
Variante 1: MailKit/MimeKit (empfohlen)
Microsoft empfiehlt System.Net.Mail.SmtpClient nicht mehr für neue Entwicklungen, weil er moderne Protokolle und Anmeldeverfahren (z. B. OAuth 2.0) nicht unterstützt. Der Standard ist MailKit mit dem Nachrichtenmodell MimeKit. Dort ist das Speichern als EML ein Einzeiler:
dotnet add package MailKit
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
var message = new MimeMessage();
message.From.Add(MailboxAddress.Parse("shop@example.com"));
message.To.Add(MailboxAddress.Parse("kunde@example.com"));
message.Subject = "Ihre Bestellung";
message.Body = new TextPart("plain") { Text = "Vielen Dank für Ihre Bestellung." };
try
{
using var smtp = new SmtpClient();
await smtp.ConnectAsync("smtp.example.com", 587, SecureSocketOptions.StartTls);
await smtp.AuthenticateAsync("benutzer", "passwort");
await smtp.SendAsync(message);
await smtp.DisconnectAsync(true);
}
catch (Exception ex)
{
var dir = Path.Combine(AppContext.BaseDirectory, "mail-fehler");
Directory.CreateDirectory(dir);
var file = Path.Combine(dir, $"{DateTime.UtcNow:yyyyMMdd-HHmmss}-{Guid.NewGuid():N}.eml");
await message.WriteToAsync(file); // komplette Mail als EML sichern
logger.LogError(ex, "Mailversand fehlgeschlagen, gesichert unter {File}", file);
}
Eine gesicherte Mail lässt sich später mit MimeMessage.Load(file) wieder einlesen und erneut versenden.
Variante 2: System.Net.Mail (Bestandscode)
Für bestehende Anwendungen mit MailMessage funktioniert der Trick über das Pickup-Verzeichnis: Ein zweiter SmtpClient „versendet“ die Mail als Datei in einen Ordner.
using System.Net.Mail;
public static class MailMessageExtensions
{
/// <summary>Speichert eine MailMessage als EML-Datei im angegebenen Ordner.</summary>
public static void Archive(this MailMessage message, string directory)
{
Directory.CreateDirectory(directory);
using var diskClient = new SmtpClient
{
DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory,
PickupDirectoryLocation = directory
};
diskClient.Send(message);
}
}
Verwendung im Fehlerfall:
try
{
smtpClient.Send(message);
}
catch (SmtpException ex)
{
message.Archive(Path.Combine(Path.GetTempPath(), "mail-fehler"));
logger.LogError(ex, "Mailversand fehlgeschlagen");
}
PickupDirectoryLocation erwartet einen absoluten Pfad zu einem existierenden Ordner. Umgebungsvariablen wie %TEMP% werden nicht aufgelöst – deshalb Path.GetTempPath() bzw. Directory.CreateDirectory verwenden. Der Dateiname wird automatisch als GUID vergeben.Hinweise
- Datenschutz: EML-Dateien enthalten personenbezogene Daten. Ablageordner nur für das Dienstkonto lesbar machen, nicht unter
wwwrootablegen und alte Dateien automatisch löschen (DSGVO). - Wiederholung: Für produktive Systeme eignet sich ein Hintergrunddienst, der den Ordner regelmäßig abarbeitet und gesicherte Mails erneut versendet.
- Microsoft 365: Der SMTP-Versand mit Basic Authentication wird bei Exchange Online abgeschaltet. MailKit unterstützt OAuth 2.0 bzw. den Versand über Microsoft Graph.
- Bei Entwicklung und Modernisierung von .NET-Anwendungen unterstützt Sie die individuelle Softwareentwicklung von m.a.x. it.
Siehe auch
Links und Quellen
- Microsoft Learn: SmtpClient-Klasse (mit Empfehlung für MailKit)
- Individuelle Softwareentwicklung von m.a.x. it
Über m.a.x. it Die m.a.x. Informationstechnologie AG ist seit über 30 Jahren IT-Partner mittelständischer und großer Unternehmen in München und bietet maßgeschneiderte Lösungen und Services in den Bereichen Cloud, Cybersecurity, Netzwerk, Windows, Linux und Softwareentwicklung. Sie haben eine Frage zu diesem Artikel oder brauchen Unterstützung?
