.NET 使用 SmtpClient 和 Mandrill SMTP 发送失败

Mul*_*ner 5 .net smtpclient mandrill

当以下代码中的mailFromName 包含“æ”、“ø”或“å”时,我们面临一个难题,通过Mandrill SMTP 发送邮件静默失败。当我们使用另一个 SMTP 时,邮件发送得非常好。

Mail.ReplyToList.Add(New MailAddress(mailFromAddress, mailFromName, System.Text.Encoding.UTF8))
Run Code Online (Sandbox Code Playgroud)

我们使用 .NET smtpClient 类。

Dim SmtpClient As New System.Net.Mail.SmtpClient
SmtpClient.Send(Mail)
SmtpClient.Dispose()
Run Code Online (Sandbox Code Playgroud)

更新

正如评论中所建议的那样,我同意这看起来像是一个编码问题,但在我们这边看不到我能做些什么。

它似乎只连接到包含 æ,ø 和 å 而不是 的 RepleyToList Mail.To,我以类似的方式定义如下:

Dim mTo As New MailAddress(mailToAddress, mailToName, System.Text.Encoding.UTF8)
Mail.To.Add(mTo)
Run Code Online (Sandbox Code Playgroud)

mailToName 可以包含 æ、ø 和 å 并且发送完全没问题。

很难证明某些事情没有发生,但我确信邮件没有发送,而且我确信它与replyToList 中的发件人名称相关联。

我怎么知道?

我在发送之前记录邮件。包含相关字符的邮件会被记录下来,但永远不会在https://mandrillapp.com/activity 中可见,也永远不会到达收件人。我删除了 æ、ø 或 å - 一切都在 Mandrill 概览中可见,一切正常。

想看我的完整代码吗?

在这里,请注意发送失败的邮件不会产生异常。

  Public Sub sendMail(ByVal mailFromAddress As String, ByVal mailFromName As String, _
                      ByVal mailToAddress As String, ByVal mailToName As String, ByVal mailCcAddress As String, ByVal mailBCcAddress As String, _
                      ByVal mailPriority As Net.Mail.MailPriority, ByVal IsBodyHtml As Boolean, ByVal mailSubject As String, _
                      ByVal bodyPlain As String, ByVal bodyHTML As String)
    Const maxtry As Integer = 3
    Dim tries As Integer = 0
    Dim failed As Boolean = False

    ' mailFromName = mailFromName.Replace("æ", "ae")

    Do
      tries += 1

      Try

        failed = False
        Dim Mail As New MailMessage


        If mailFromAddress <> String.Empty Then
          'Mail.ReplyTo = New MailAddress(mailFromAddress, mailFromName, System.Text.Encoding.UTF8)
          Mail.ReplyToList.Add(New MailAddress(mailFromAddress, mailFromName, System.Text.Encoding.UTF8))
        Else
          'Mail.ReplyTo = New MailAddress(Me.MailAddressFrom, Me.MailAddressDisplayName, System.Text.Encoding.UTF8)
          Mail.ReplyToList.Add(New MailAddress(Me.MailAddressFrom, Me.MailAddressDisplayName, System.Text.Encoding.UTF8))
        End If
        Mail.From = New MailAddress(Me.MailAddressFrom, Me.MailAddressDisplayName, System.Text.Encoding.UTF8)
        Mail.Sender = New MailAddress(Me.MailAddressFrom, Me.MailAddressDisplayName, System.Text.Encoding.UTF8)

        If mailToAddress <> String.Empty Then
          Dim mTo As New MailAddress(mailToAddress, mailToName, System.Text.Encoding.UTF8) 'UTF8
          Mail.To.Add(mTo)
        End If
        If mailCcAddress <> String.Empty Then
          Dim mCc As New MailAddress(mailCcAddress)
          Mail.CC.Add(mCc)
        End If
        If mailBCcAddress <> String.Empty Then
          Dim mBCc As New MailAddress(mailBCcAddress)
          Mail.Bcc.Add(mBCc)
        End If

        Mail.Priority = mailPriority

        Mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure

        Mail.IsBodyHtml = IsBodyHtml 
        Mail.HeadersEncoding = Encoding.GetEncoding("utf-8")

        Mail.Subject = mailSubject
        Mail.SubjectEncoding = Encoding.GetEncoding("utf-8") ' = System.Text.Encoding.Default 'UTF8 'Default ' Test on all possible encodings

        If IsBodyHtml Then
          Mail.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(bodyHTML, System.Text.Encoding.Default, "text/html"))
        End If
        Mail.BodyEncoding = Encoding.GetEncoding("utf-8")
        Mail.Body = bodyPlain

        ' Add to log
        addToMailLog(mailToAddress, mailCcAddress, mailSubject, bodyPlain)

        ' Send
        Dim SmtpClient As New System.Net.Mail.SmtpClient
        'SmtpClient.ServicePoint.MaxIdleTime = 1
        SmtpClient.Send(Mail)
        Me._status = EMailStatus.EOkay
        SmtpClient.Dispose()

      Catch ex As Exception
        Dim debugInfo As New CDebug("sendMail", "Try: " & tries.ToString & ", UserId: " & Me.UserId, ex.ToString, Me.UserId, String.Empty)
        Me._status = EMailStatus.EMailSendError
        failed = True
      End Try

    Loop Until (failed = False Or tries >= maxtry)

  End Sub
Run Code Online (Sandbox Code Playgroud)

更新二

我现在已经使用 WireShark 跟踪了 SMTP 通信。请参阅屏幕截图,该屏幕截图显示了未发送且未显示在 Mandrill 活动列表中的邮件的通信 - 即使我们获得 SMTP 响应正常且已排队 id。

smtp 捕获

我举三个例子:

发表:

mailFromName = "xxx xxxxxxxxx xxxx - xxxxxxxxxx xxxxxxx xxxxxxxxx"
Run Code Online (Sandbox Code Playgroud)

没送到:

mailFromName = "xxx xxxxxxxxx xxxx - xxxxxxxxxx xxxxxxx xxxxxxæxx"
Run Code Online (Sandbox Code Playgroud)

发表:

mailFromName = "æxx xxxxxxxxx xxxx - xxxxxxxxxx xxxxxxx xxxxxxxxx"
Run Code Online (Sandbox Code Playgroud)

Mul*_*ner 3

我相信我已经找到了对此的解释。smtpclient 似乎在主题和回复显示名称的大约 72 个字符后添加了一个新行。问题是这似乎是在字符串编码之后发生的。因此,在某些情况下,在编码字符的中间添加新的行字符,这显然是非法的。

我不确定为什么 Mandrill SMTP 服务器失败而不返回错误,而其他 SMTP 服务器可以很好地处理这种情况。

现在我明白发生了什么,我必须找到一种方法来解决它 - 最好的建议可以获得赏金。