gpt4 book ai didi

.Net smtp 使用 SmtpStatusCode 发送 - 什么时候应该重试?

转载 作者:行者123 更新时间:2023-12-03 18:58:40 26 4
gpt4 key购买 nike

我有一项发送电子邮件并将出站电子邮件存储在数据库中的服务。我正在使用 .NET native Smtp 类进行电子邮件传输。如果电子邮件发送失败,我会设置一个错误标志。

我的服务会定期检查未送达的消息并尝试重新发送。在什么情况下应该重试发送邮件?我注意到,即使电子邮件地址不正确,它也会引发异常,但我希望我的服务丢弃任何无效的电子邮件,否则它将永远重试。

基本上,我想捕获很有可能重新发送电子邮件的异常。我想这只是网络错误,而不是电子邮件帐户。哪个 SmtpStatusCode 将指示值得重试:

http://msdn.microsoft.com/en-us/library/system.net.mail.smtpstatuscode.aspx

最佳答案

我正在尝试解决与您完全相同的问题。我想出的解决方案涉及大约一个小时的时间,通过 RFC2821 倾注并尽可能地解释它。如果您有兴趣,可以在这里找到它 - http://www.rfc-editor.org/rfc/rfc2821.txt

阅读 RFC 的最大收获是 4yz 形式的代码表示瞬时负完成代码,需要重试。 5yz 形式的代码表示永久否定完成代码,您不应重试。

因此,我们的目标是过滤掉需要重试和不需要重试的收件人。所有 5yz 代码都可以解释为“不要重试”,但 552 除外,某些服务器可能会错误地发送该代码而不是 452。从那时起,您需要决定:

  • 这是一个严重的技术错误 (503 BadCommandSequence),它会导致您的服务快速失败而无需重试任何操作。

  • 这是只适用于单个收件人的否定永久完成代码吗?在这种情况下,您只需忽略有问​​题的收件人并重试发送操作。

因此,我的做法是这样的:

  • 处理 SmtpFailedRecipientsExceptionSmtpFailedRecipientException
  • 将所有失败的收件人存储到列表中。
  • 对于每个失败的收件人,调用我的特殊 HandleFailedRecipient() 方法来解释 SMTP 代码。如果该方法在任何时候返回 false,则表明出现了更严重的错误,我的服务应该会很快失败(无需尝试重​​新发送电子邮件)。
  • 否则,该方法可能会或可能不会重新添加收件人(取决于 SMTP 代码)。
  • 最后,如果邮件仍有剩余收件人,请尝试重新发送。

这是我解释 SMTP 代码的方法:

    private bool HandleFailedRecipient(MailMessage message, string emailAddress, SmtpStatusCode statusCode, AddressType addressType)
{
//Notify any event subscribers that a recipient failed and give them the SMTP code.
RecipientFailedOnSend(this, new MailAddressEventArgs() { Address = emailAddress, AddressType = addressType, StatusCode = statusCode });

//5yz codes typically indicate a 'Permanent Negative Completion reply', which means we should NOT keep trying to send the message.
//The codes below can be interpreted as exceptions to the rule. In these cases we will just strip the user and try to resend.
if (statusCode == SmtpStatusCode.MailboxUnavailable || //550 = "No such user"
statusCode == SmtpStatusCode.MailboxNameNotAllowed || //553 = "User name ambiguous"
statusCode == SmtpStatusCode.UserNotLocalTryAlternatePath || //551 = "Mail address not deliverable"
statusCode == SmtpStatusCode.TransactionFailed) //554 = "Transaction failed / no valid recipients"
{
return true;
}

//The 4yz codes are 'Transient Negative Completion reply' codes, which means we should re-add the recipient and let the calling routine try again after a timeout.
if (statusCode == SmtpStatusCode.ServiceNotAvailable ||
statusCode == SmtpStatusCode.MailboxBusy ||
statusCode == SmtpStatusCode.LocalErrorInProcessing ||
statusCode == SmtpStatusCode.InsufficientStorage ||
statusCode == SmtpStatusCode.ClientNotPermitted ||
//The ones below are 'Positive Completion reply' 2yz codes. Not likely to occur in this scenario but we will account for them anyway.
statusCode == SmtpStatusCode.SystemStatus ||
statusCode == SmtpStatusCode.HelpMessage ||
statusCode == SmtpStatusCode.ServiceReady ||
statusCode == SmtpStatusCode.ServiceClosingTransmissionChannel ||
statusCode == SmtpStatusCode.Ok ||
statusCode == SmtpStatusCode.UserNotLocalWillForward ||
statusCode == SmtpStatusCode.CannotVerifyUserWillAttemptDelivery ||
statusCode == SmtpStatusCode.StartMailInput ||
statusCode == SmtpStatusCode.CannotVerifyUserWillAttemptDelivery ||
//The code below (552) may be sent by some incorrect server implementations instead of 452 (InsufficientStorage).
statusCode == SmtpStatusCode.ExceededStorageAllocation)
{
if ((addressType & AddressType.To) != 0)
{
message.To.Add(emailAddress);
}
if ((addressType & AddressType.CC) != 0)
{
message.CC.Add(emailAddress);
}
if ((addressType & AddressType.BCC) != 0)
{
message.Bcc.Add(emailAddress);
}
return true;
}

//Anything else indicates a very serious error (probably of the 5yz variety that we haven't handled yet). Tell the calling routine to fail fast.
return false;
}

让我知道这是否有意义,或者您是否需要查看更多代码,但从这里开始应该相对清晰。

关于.Net smtp 使用 SmtpStatusCode 发送 - 什么时候应该重试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6213741/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com