Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在c中检查电子邮件状态是否已发送#_C#_Asp.net_Email_Smtp_Smtpexception - Fatal编程技术网

C# 如何在c中检查电子邮件状态是否已发送#

C# 如何在c中检查电子邮件状态是否已发送#,c#,asp.net,email,smtp,smtpexception,C#,Asp.net,Email,Smtp,Smtpexception,目前我通过SMTP发送邮件,下面给出了代码 SmtpClient client = new SmtpClient(); client.DeliveryMethod = SmtpDeliveryMethod.Network; //client.EnableSsl = true; client.Send(msg); 我必须使用代码检查邮件已发送或未使用smtp异常的发送状态您无法检查它。因为您使用的是SMTP,所以无法判断传递是否成功。邮件在传递时被路由。 一些有用的技巧是在发送电子邮件之前验证电

目前我通过SMTP发送邮件,下面给出了代码

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

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

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

虽然@Chase在技术上是正确的,但如果路由上的SMTP服务器支持此扩展,则可以获取传递状态通知

我不知道如何使用System.Net.Mail实现这一点,但通过,您实际上可以为收件人请求传递状态通知

在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);
}
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
    }
}
现在的情况是,无论何时出现成功或失败通知,您都会收到一封发送到您帐户收件箱的电子邮件(POP3或IMAP,具体取决于您使用的内容),其中将包含一个
多部分/报告
MIME部分,该部分通常包含3个其他MIME部分:一个人类可读的解释,一个
message/delivery status
MIME部分,其主体包含一些键/值对,第三部分包含原始消息(有时仅包含标题)

目前,MailKit没有专门的MIME类来处理
message/delivery status
MIME部分,但您可以通过解析如下内容来解决此问题:

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);
}
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
    }
}
var mds=message.BodyParts.OfType.Where(x=>x.ContentType.Matches(“消息”、“传递状态”)).FirstOrDefault();
如果(mds!=null){
使用(var memory=newmemoryStream()){
mds.ContentObject.decodito(内存);
记忆位置=0;
//消息/传递状态MIME部分的内容是
//标题组的集合。第一组标题
//将包含每封邮件的状态标头,而
//之后的组将包含
//特定收件人。
var group=新列表();
while(memory.Position

更新:我在MimeKit中添加了一个MessageDeliveryStatus类,用于为您解析
message/delivery status
MIME部件的内容,但可能需要2周才能发布另一个版本,因为我两天前刚刚发布了一个版本。当我发布它时,希望在MimeKit 1.2.8中找到此新类。

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

我不知道如何使用System.Net.Mail实现这一点,但通过,您实际上可以为收件人请求传递状态通知

在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);
}
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
    }
}
现在的情况是,无论何时出现成功或失败通知,您都会收到一封发送到您帐户收件箱的电子邮件(POP3或IMAP,具体取决于您使用的内容),其中将包含一个
多部分/报告
MIME部分,该部分通常包含3个其他MIME部分:一个人类可读的解释,一个
message/delivery status
MIME部分,其主体包含一些键/值对,第三部分包含原始消息(有时仅包含标题)

目前,MailKit没有专门的MIME类来处理
message/delivery status
MIME部分,但您可以通过解析如下内容来解决此问题:

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);
}
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
    }
}
var mds=message.BodyParts.OfType.Where(x=>x.ContentType.Matches(“消息”、“传递状态”)).FirstOrDefault();
如果(mds!=null){
使用(var memory=newmemoryStream()){
mds.ContentObject.DecodeTo(内存);
记忆位置=0;
//消息/传递状态MIME部分的内容是
//标题组的集合。第一组标题
//将包含每封邮件的状态标头,而
//之后的组将包含
//特定收件人。
变量组=新列表();
while(memory.Position

更新:我在MimeKit中添加了一个MessageDeliveryStatus类,用于为您解析
message/delivery status
MIME部件的内容,但可能需要2周才能发布另一个版本,因为我两天前刚刚发布了一个版本。希望在我发布MimeKit 1.2.8时能找到这个新类。

嗨,Chase,你能详细说明一下你的观点吗“邮件在传递时被路由”嘿,你可以在那里读到它,