如何在 c# 中检查电子邮件状态是否有效

本文关键字:电子邮件 状态 是否 有效 检查 | 更新日期: 2023-09-27 18:01:05

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

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

我必须使用代码检查邮件是否已解除或未使用 smtp 异常的 deliever 状态

如何在 c# 中检查电子邮件状态是否有效

虽然@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 没有用于处理message/delivery-status MIME 部分的特殊 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 中找到它。

您无法检查它。由于您使用 SMTP,因此无法判断交付是否成功。邮件在传递时路由。一些有用的技巧是在发送之前验证电子邮件地址是否有效,并将单个无回复地址设置为实际收件箱,然后使用 POP3 进入电子邮件帐户并查找退回邮件。详细说明 SMTP 的工作原理