Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/34.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
ASP.NET邮件工具包SMTP响应_Asp.net_Mailkit - Fatal编程技术网

ASP.NET邮件工具包SMTP响应

ASP.NET邮件工具包SMTP响应,asp.net,mailkit,Asp.net,Mailkit,我有这个代码,它已经成功地发送电子邮件-除了前几天它没有。因此,我想检查SMTP响应,但不确定要做什么 这是我现在的代码: using (var client = new SmtpClient()) { client.LocalDomain = "xxxxxxxxxxxx"; await client.ConnectAsync("xxxxxxxxxxxx", xx, SecureSocketOptions.StartTls).ConfigureAwait(false); await

我有这个代码,它已经成功地发送电子邮件-除了前几天它没有。因此,我想检查SMTP响应,但不确定要做什么

这是我现在的代码:

using (var client = new SmtpClient())
{
  client.LocalDomain = "xxxxxxxxxxxx";
  await client.ConnectAsync("xxxxxxxxxxxx", xx, SecureSocketOptions.StartTls).ConfigureAwait(false);
  await client.AuthenticateAsync( new System.Net.NetworkCredential("xxxxxxxxxxxx", "xxxxxxxxxxxx")).ConfigureAwait(false);
  await client.SendAsync(emailMessage).ConfigureAwait(false);
  await client.DisconnectAsync(true).ConfigureAwait(false);
}
因此,我阅读了onMessageSent,或者MessageSent函数可以用来查看是否有响应——我真的很想看一个代码示例,如何在代码中使用这些函数来确定消息是否真的收到了

我确实有一个函数,其中包含异步发送函数作为一个
公共无效
,并且警告抑制功能可以平息VisualStudio对未等待呼叫的投诉

public void SendEmail(string HtmlEmailContents, string SubjectLine, string CustomFromAddress = null, string CustomEmailRecipients = null)
{
  string To = getRecipientString(mainRecipients);
  string Cc = getRecipientString(ccRecipients);
  string Bcc = getRecipientString(bccRecipients);
  if(CustomEmailRecipients != null && CustomEmailRecipients != "")
  {
    To = CustomEmailRecipients;
    Cc = "";
    Bcc = "";
  }
  string finalizedFromAddress;
  if(CustomFromAddress != null)
  {
    finalizedFromAddress = CustomFromAddress;
  }
  else
  {
    finalizedFromAddress = FromAddress;
  }
  #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
  MessageServices.SendEmailAsync(
    To,
    finalizedFromAddress,
    Cc,
    Bcc,
    SubjectLine,
    HtmlEmailContents
  );
  #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
[新编辑]:那么,让我们想象一下,我解决了整个异步问题,现在是时候真正捕捉那些错误消息了。在这里,我读到MessageSent和OnMessageSent函数可以用来查看结果。当然,我想不出来。 我正在寻找一些可以使用MailKit镜像的示例。
其中,行
client.sendpleted+=new-sendpletedeventhandler(sendpletedcallback)
似乎掌握了关键,我想知道,在我的代码中,使用
client.MessageSent+=?
我们是否是MailKit中的对应项。

最初的问题似乎由@mason就异步的误用给出了回答

现在来回答你的新问题

该事件与.NET中的任何其他事件一样,可以通过以下方式收听:

client.MessageSent += OnMessageSent;
其中,
onMessagement
方法如下:

void OnMessageSent (object sender, MessageSentEventArgs e)
{
    Console.WriteLine ("The message was sent!");
}
public void ProcessDeliveryStatusNotification (MimeMessage message)
{
    var report = message.Body as MultipartReport;

    if (report == null || report.ReportType == null || !report.ReportType.Equals ("delivery-status", StringComparison.OrdinalIgnoreCase)) {
        // this is not a delivery status notification message...
        return;
    }

    // process the report
    foreach (var mds in report.OfType<MessageDeliveryStatus> ()) {
        // process the status groups - each status group represents a different recipient

        // The first status group contains information about the message
        var envelopeId = mds.StatusGroups[0]["Original-Envelope-Id"];

        // all of the other status groups contain per-recipient information
        for (int i = 1; i < mds.StatusGroups.Length; i++) {
            var recipient = mds.StatusGroups[i]["Original-Recipient"];
            var action = mds.StatusGroups[i]["Action"];

            if (recipient == null)
                recipient = mds.StatusGroups[i]["Final-Recipient"];

            // the recipient string should be in the form: "rfc822;user@domain.com"
            var index = recipient.IndexOf (';');
            var address = recipient.Substring (index + 1);

            switch (action) {
            case "failed":
                Console.WriteLine ("Delivery of message {0} failed for {1}", envelopeId, address);
                break;
            case "delayed":
                Console.WriteLine ("Delivery of message {0} has been delayed for {1}", envelopeId, address);
                break;
            case "delivered":
                Console.WriteLine ("Delivery of message {0} has been delivered to {1}", envelopeId, address);
                break;
            case "relayed":
                Console.WriteLine ("Delivery of message {0} has been relayed for {1}", envelopeId, address);
                break;
            case "expanded":
                Console.WriteLine ("Delivery of message {0} has been delivered to {1} and relayed to the the expanded recipients", envelopeId, address);
                break;
            }
        }
    }
}
然而,你之所以想听这个活动,似乎是因为对它真正为你提供了什么信息的误解

虽然属性包含服务器发送的实际响应,但它不太可能告诉您收件人电子邮件地址是否确实存在

如果您正在向不存在的电子邮件地址发送邮件,并且
SmtpClient.Send()
sendsync()
不会引发异常,然后,这意味着SMTP服务器在接收到MailKit发送的
RCPT TO
命令时,可能没有验证电子邮件地址是否存在,并将愉快地接受邮件提交w/o错误,这意味着MailKit不会引发异常。许多SMTP服务器这样做有两个原因:

  • 保护其用户的匿名性(因此垃圾邮件发送者不能使用暴力技术来确定其用户的帐户名-这与man禁用
    VRFY
    EXPN
    命令的原因相同)
  • 延迟查找电子邮件地址-即SMTP服务器在将邮件转发到适当的域之前不会实际查找电子邮件地址的存在
  • 例如,如果您连接到smtp.gmail.com向另一个域上的用户发送消息,那么smtp.gmail.com就无法知道这一点user@another-domain.com不存在,直到它实际尝试将邮件转发到smtp.Other-domain.com

    如果你真的想得到关于电子邮件地址是否确实存在的反馈,那么这个过程将需要你付出更多的努力和一些运气

    祝你好运。 首先,您需要希望并祈祷您的SMTP服务器支持(传递状态通知)扩展

    要检查您的服务器是否支持此功能,您可以检查:

    努力。 假设您的服务器支持DSN扩展,接下来您需要对SmtpClient进行子类化,以便可以覆盖某些方法,以便为MailKit的SmtpClient提供一些所需的信息/选项

    这些方法是:

  • 这两种方法的文档已经提供了以下代码片段,但我将把它粘贴到这里供后人使用:

    public class DSNSmtpClient : SmtpClient
    {
        public DSNSmtpClient ()
        {
        }
    
        /// <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)
        {
            // Since you will want to be able to map whatever identifier you return here to the
            // message, the obvious identifier to use is probably the Message-Id value.
            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)
        {
            // In this example, we only want to be notified of failures to deliver to a mailbox.
            // If you also want to be notified of delays or successful deliveries, simply bitwise-or
            // whatever combination of flags you want to be notified about.
            return DeliveryStatusNotification.Failure;
        }
    }
    
    然后,您需要定位具有
    消息/传递状态的
    内容类型
    的MIME部分,这些MIME部分是
    多部分/报告
    的子部分(每个部分将由以下内容表示):

    在以下每个状态组中,您都需要获取
    “原始收件人”
    的值(如果设置了,否则我想您可以检查
    “最终收件人”
    )。其形式为
    rfc822;user@domain.com
    -所以只需在
    上拆分;'字符并使用第二个字符串

    最后,您需要检查
    “Action”
    值,以了解所述收件人的状态。在您的情况下,如果值为
    “failed”
    ,则表示传递失败

    for (int i = 1; i < mds.StatusGroups.Length; i++) {
        var recipient = mds.StatusGroups[i]["Original-Recipient"];
        var action = mds.StatusGroups[i]["Action"];
    
        if (recipient == null)
            recipient = mds.StatusGroups[i]["Final-Recipient"];
    
        var values = recipient.Split (';');
        var emailAddress = values[1];
    
        ...
    }
    
    for(int i=1;i
    如果你把它们放在一起,你会得到这样的结果:

    void OnMessageSent (object sender, MessageSentEventArgs e)
    {
        Console.WriteLine ("The message was sent!");
    }
    
    public void ProcessDeliveryStatusNotification (MimeMessage message)
    {
        var report = message.Body as MultipartReport;
    
        if (report == null || report.ReportType == null || !report.ReportType.Equals ("delivery-status", StringComparison.OrdinalIgnoreCase)) {
            // this is not a delivery status notification message...
            return;
        }
    
        // process the report
        foreach (var mds in report.OfType<MessageDeliveryStatus> ()) {
            // process the status groups - each status group represents a different recipient
    
            // The first status group contains information about the message
            var envelopeId = mds.StatusGroups[0]["Original-Envelope-Id"];
    
            // all of the other status groups contain per-recipient information
            for (int i = 1; i < mds.StatusGroups.Length; i++) {
                var recipient = mds.StatusGroups[i]["Original-Recipient"];
                var action = mds.StatusGroups[i]["Action"];
    
                if (recipient == null)
                    recipient = mds.StatusGroups[i]["Final-Recipient"];
    
                // the recipient string should be in the form: "rfc822;user@domain.com"
                var index = recipient.IndexOf (';');
                var address = recipient.Substring (index + 1);
    
                switch (action) {
                case "failed":
                    Console.WriteLine ("Delivery of message {0} failed for {1}", envelopeId, address);
                    break;
                case "delayed":
                    Console.WriteLine ("Delivery of message {0} has been delayed for {1}", envelopeId, address);
                    break;
                case "delivered":
                    Console.WriteLine ("Delivery of message {0} has been delivered to {1}", envelopeId, address);
                    break;
                case "relayed":
                    Console.WriteLine ("Delivery of message {0} has been relayed for {1}", envelopeId, address);
                    break;
                case "expanded":
                    Console.WriteLine ("Delivery of message {0} has been delivered to {1} and relayed to the the expanded recipients", envelopeId, address);
                    break;
                }
            }
        }
    }
    
    public void ProcessDeliveryStatusNotification(MimeMessage消息)
    {
    var report=message.Body作为MultipartReport;
    if(report==null | | | | report.ReportType==null | | |!report.ReportType.Equals(“交付状态”,StringComparison.OrdinalingOreCase)){
    //这不是传递状态通知消息。。。
    返回;
    }
    //处理报告
    foreach(report.OfType()中的var mds){
    //处理状态组-每个状态组代表不同的收件人
    //第一个状态组包含有关消息的信息
    var envelopeId=mds.StatusGroups[0][“原始信封Id”];
    //所有其他状态组都包含每个收件人的信息
    对于(int i=1;ifor (int i = 1; i < mds.StatusGroups.Length; i++) {
        var recipient = mds.StatusGroups[i]["Original-Recipient"];
        var action = mds.StatusGroups[i]["Action"];
    
        if (recipient == null)
            recipient = mds.StatusGroups[i]["Final-Recipient"];
    
        var values = recipient.Split (';');
        var emailAddress = values[1];
    
        ...
    }
    
    public void ProcessDeliveryStatusNotification (MimeMessage message)
    {
        var report = message.Body as MultipartReport;
    
        if (report == null || report.ReportType == null || !report.ReportType.Equals ("delivery-status", StringComparison.OrdinalIgnoreCase)) {
            // this is not a delivery status notification message...
            return;
        }
    
        // process the report
        foreach (var mds in report.OfType<MessageDeliveryStatus> ()) {
            // process the status groups - each status group represents a different recipient
    
            // The first status group contains information about the message
            var envelopeId = mds.StatusGroups[0]["Original-Envelope-Id"];
    
            // all of the other status groups contain per-recipient information
            for (int i = 1; i < mds.StatusGroups.Length; i++) {
                var recipient = mds.StatusGroups[i]["Original-Recipient"];
                var action = mds.StatusGroups[i]["Action"];
    
                if (recipient == null)
                    recipient = mds.StatusGroups[i]["Final-Recipient"];
    
                // the recipient string should be in the form: "rfc822;user@domain.com"
                var index = recipient.IndexOf (';');
                var address = recipient.Substring (index + 1);
    
                switch (action) {
                case "failed":
                    Console.WriteLine ("Delivery of message {0} failed for {1}", envelopeId, address);
                    break;
                case "delayed":
                    Console.WriteLine ("Delivery of message {0} has been delayed for {1}", envelopeId, address);
                    break;
                case "delivered":
                    Console.WriteLine ("Delivery of message {0} has been delivered to {1}", envelopeId, address);
                    break;
                case "relayed":
                    Console.WriteLine ("Delivery of message {0} has been relayed for {1}", envelopeId, address);
                    break;
                case "expanded":
                    Console.WriteLine ("Delivery of message {0} has been delivered to {1} and relayed to the the expanded recipients", envelopeId, address);
                    break;
                }
            }
        }
    }