System.Net.Mail.SmtpException : SMTP command timeout - closing connection
-
09-06-2021 - |
سؤال
I am having an error that is occurring sporadically. When I encounter this error, if I try again, the e-mail will send. I cannot reliably reproduce the error, but it is hapening frequently enough to be a problem.
System.Net.Mail.SmtpException : Service not available, closing transmission channel. The server response was: [Servername]: SMTP command timeout - closing connection
Stack Trace:
at System.Net.Mail.MailCommand.CheckResponse(SmtpStatusCode statusCode, String response) at System.Net.Mail.MailCommand.Send(SmtpConnection conn, Byte[] command, String from) at System.Net.Mail.SmtpTransport.SendMail(MailAddress sender, MailAddressCollection recipients, String deliveryNotify, SmtpFailedRecipientException& exception) at System.Net.Mail.SmtpClient.Send(MailMessage message)
Here's the code in question. It uses an HTML template (database driven with a web url default backup) to inject values and create an html e-mail.
public void AccountActivationEmail(Common.Request.Email.AccountActivation request)
{
var profile = profileRepository.GetOne(new ProfileByUsername(request.Username, request.SiteId));
var options = siteService.GetOptions(new GatewayOptionsRequest()
{
SiteId = request.SiteId
});
var site = options.Site;
ExpiringHMAC hmac = new ExpiringHMAC(request.ExpireOn, new string[] { request.AccountId.ToString(), request.AccountKey.ToString(), request.Username });
Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("{{logourl}}", String.IsNullOrEmpty(options.FullyHostedGateway.LogoUrl) ? UrlHelper.ConvertRelativeToAbsolute("/content/images/spacer.png") : options.FullyHostedGateway.LogoUrl);
data.Add("{{name}}", profile.Name.DisplayName);
data.Add("{{sitename}}", site.Name.DisplayName);
data.Add("{{activationlink}}", String.Format(ActivationUrlFormat, options.UrlFriendlyName, Encryption.EncryptQueryString(request.Username), hmac.ToString()));
MailDefinition template = new MailDefinition();
MailMessage message = null;
var emailTemplate = options.GetEmailTemplate(EmailTemplateType.ActivateAccount);
string defaultSubject = "Activate Account";
bool hasTemplate = false;
if (emailTemplate != null)
{
hasTemplate = !String.IsNullOrEmpty(emailTemplate.Template);
}
if (!hasTemplate)
{
template.BodyFileName = activationDefaultTemplateUrl;
message = template.CreateMailMessage(request.EmailAddress, data, new System.Web.UI.LiteralControl());
message.IsBodyHtml = true;
message.Subject = defaultSubject;
}
else
{
message = template.CreateMailMessage(request.EmailAddress, data, emailTemplate.Template, new System.Web.UI.LiteralControl());
message.IsBodyHtml = emailTemplate.IsHtml;
if (!String.IsNullOrEmpty(emailTemplate.Subject))
message.Subject = emailTemplate.Subject;
else
message.Subject = defaultSubject;
}
if (options.ContactDetails != null)
{
if (!String.IsNullOrEmpty(options.ContactDetails.EmailAddress))
message.From = new MailAddress(options.ContactDetails.EmailAddress);
}
SmtpClient client = new SmtpClient();
client.Send(message);
}
This code is part of a class that is generated as a singleton using Structuremap. I thought maybe that might be causing the issue, but every time the method is called, a new SmtpClient object is created, which should eliminate the problems I have seen about using the same connection to send multiple e-mails.
We have nothing blocking or restricting the connection, which is the official stance our e-mail hosting is taking on this issue. I want to see if there's any way to do this better so I don't get these errors.
EDIT:
I do have my mail server defined in my web.config. I have confirmed with my e-mail hosting that my settings are correct.
<system.net>
<mailSettings>
<smtp deliveryMethod="Network" from="no-reply@mydomain.com">
<network host="smtp.emailhost.com" userName="someaddress@mydomain.com"
password="myPassword1" port="2500" />
</smtp>
</mailSettings>
</system.net>
المحلول
Are you disposing of the Smtp Client object after sending? From http://connect.microsoft.com/VisualStudio/feedback/details/337557/smtpclient-does-not-close-session-after-sending-message it would appear that "...even if you are creating a new instance of the SmtpClient every time, it still uses the same unerlying session."
So perhaps
using (SmtpClient client = new SmtpClient())
{
client.Send(message);
}