如何检查电子邮件状态是否已在c#中删除

时间:2015-07-04 12:11:18

标签: c# asp.net email smtp smtpexception

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

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

我必须使用代码

检查邮件是否已被删除或使用smtp异常的delievery状态

2 个答案:

答案 0 :(得分:2)

虽然@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中找到这个新类。

答案 1 :(得分:1)

你无法检查它。因为您使用 SMTP ,所以无法判断传递是否成功。邮件在发送时被路由。 一些有用的技巧是在发送电子邮件地址之前验证电子邮件地址是否有效,并将单个无回复地址设置为实际收件箱,然后使用 POP3 进入电子邮件帐户并查找退回邮件。 Details how SMTP works