Skip to main content
 首页 » 编程设计

c#之C#查看邮件状态是否送达

2024年06月03日40xing901022

目前我正在通过 SMTP 发送邮件代码如下

SmtpClient client = new SmtpClient(); 
client.DeliveryMethod = SmtpDeliveryMethod.Network; 
//client.EnableSsl = true; 
client.Send(msg); 

我必须使用代码使用 smtp 异常检查邮件已发送或未发送的发送状态

请您参考如下方法:

虽然@Chase 在技术上是正确的,但如果沿途的 SMTP 服务器支持此扩展,则可能获得传递状态通知。

我不知道用 System.Net.Mail 做这个的方法,但是用 MailKit ,您实际上可以为您的收件人请求递送状态通知。

在 MailKit 中,您需要做的第一件事(直到我为此找到更好的 API 之前)是设置您自己的 SmtpClient 类,如下所示:

class MySmtpClient : SmtpClient 
{ 
    public MySmtpClient () 
    { 
    } 
 
    /// <summary> 
    /// Get the envelope identifier to be used with delivery status notifications. 
    /// </summary> 
    /// <remarks> 
    /// <para>The envelope identifier, if non-empty, is useful in determining which message 
    /// a delivery status notification was issued for.</para> 
    /// <para>The envelope identifier should be unique and may be up to 100 characters in 
    /// length, but must consist only of printable ASCII characters and no white space.</para> 
    /// <para>For more information, see rfc3461, section 4.4.</para> 
    /// </remarks> 
    /// <returns>The envelope identifier.</returns> 
    /// <param name="message">The message.</param> 
    protected override string GetEnvelopeId (MimeMessage message) 
    { 
        // The Message-Id header is probably the easiest way to go... 
        return message.MessageId; 
    } 
 
    /// <summary> 
    /// Get the types of delivery status notification desired for the specified recipient mailbox. 
    /// </summary> 
    /// <remarks> 
    /// Gets the types of delivery status notification desired for the specified recipient mailbox. 
    /// </remarks> 
    /// <returns>The desired delivery status notification type.</returns> 
    /// <param name="message">The message being sent.</param> 
    /// <param name="mailbox">The mailbox.</param> 
    protected override DeliveryStatusNotification? GetDeliveryStatusNotifications (MimeMessage message, MailboxAddress mailbox) 
    { 
        // Since you want to know whether the message got delivered or not, 
        // you'll probably want to get notifications for Success and Failure. 
        return DeliveryStatusNotification.Success | DeliveryStatusNotification.Failure; 
    } 
} 

然后,一旦你有了它,你就可以像这样使用它:

using (var client = new MySmtpClient ()) { 
    client.Connect ("smtp.gmail.com", 465, true); 
    client.Authenticate ("username", "password"); 
    client.Send (message); 
    client.Disconnect (true); 
} 

现在会发生的是,无论何时有成功或失败通知,您都会收到一封发送到您帐户收件箱(POP3 或 IMAP,具体取决于您使用的是什么)的电子邮件,其中包含 multipart/report MIME 部分通常包含 3 个其他 MIME 部分:一个人类可读的解释,一个 message/delivery-status MIME 部分,它有一个包含一些键/值对的主体和一个第三方部分其中包含原始消息(或有时仅包含标题)。

目前,MailKit 没有专门的 MIME 类来处理 message/delivery-status MIME 部分,但是您可以通过像这样解析内容来解决这个问题:

var mds = message.BodyParts.OfType<MimePart>.Where (x => x.ContentType.Matches ("message", "delivery-status")).FirstOrDefault (); 
if (mds != null) { 
    using (var memory = new MemoryStream ()) { 
        mds.ContentObject.DecodeTo (memory); 
        memory.Position = 0; 
 
        // the content of a message/delivery-status MIME part is a 
        // collection of header groups. The first group of headers 
        // will contain the per-message status headers while each 
        // group after that will contain status headers for a 
        // particular recipient. 
        var groups = new List<HeaderList> (); 
        while (memory.Position < memory.Length) 
            groups.Add (HeaderList.Load (memory)); 
 
        // TODO: take a look at the specific "headers" to get the info we  
        // care about. For more info on what these header field names and 
        // values are, take a look at https://tools.ietf.org/html/rfc3464 
    } 
} 

更新:我在 MimeKit 中添加了一个 MessageDeliveryStatus 类,用于为您解析 message/delivery-status MIME 部分的内容,但它可能需要自从 2 天前我刚发布了一个版本以来,在我发布另一个版本之前的 2 周。当我发布它时,期望在 MimeKit 1.2.8 中找到这个新类。