Strange .NET Mail behaviour with Disposables - asp.net

Recently been going through a bunch of code tidying up and "improving" things, I noticed this bit of code used for sending emails:
Dim SmtpServer As New SmtpClient() With {
.Port = 25,
.Host = Email.Hostname,
.Credentials = New NetworkCredential() With {
.UserName = Email.UserName,
.Password = Email.Password
}
}
Dim mail As New MailMessage() With {
.From = Email.Sender,
.Subject = Email.Subject,
.IsBodyHtml = True,
.Body = Email.WrappedHtml
}
If Not Email.Attachments Is Nothing Then
For Each a In Email.Attachments
mail.Attachments.Add(a)
Next
End If
mail.To.Add(New MailAddress(Email.Recipient.Email, Email.Recipient.Name))
Call SmtpServer.Send(mail)
SmtpServer.Dispose()
mail.Dispose()
SmtpServer = Nothing
mail = Nothing
In that example the Email Object is a Class containing basic email information, recipients, sender, attachments etc.
The code above works perfectly....
But, I noticed that SmtpServer and MailMessage are both Disposable objects, and it would be better practice to wrap them in Using statements, thus:
Using SmtpServer As New SmtpClient() With {
.Port = 25,
.Host = Email.Hostname,
.Credentials = New NetworkCredential() With {
.UserName = Email.UserName,
.Password = Email.Password
}
}
Using mail As New MailMessage() With {
.From = Email.Sender,
.Subject = Email.Subject,
.IsBodyHtml = True,
.Body = Email.WrappedHtml
}
If Not Email.Attachments Is Nothing Then
For Each a In Email.Attachments
mail.Attachments.Add(a)
Next
End If
mail.To.Add(New MailAddress(Email.Recipient.Email, Email.Recipient.Name))
Call SmtpServer.Send(mail)
End Using
End Using
However... when I do that, and send more than a couple of emails in quick succession I get:
System.Net.Mail.SmtpException: Failure sending mail. ---> System.IO.IOException: Unable to read data from the transport connection: net_io_connectionclosed. at System.Net.Mail.SmtpReplyReaderFactory.ProcessRead(Byte[] buffer, Int32 offset, Int32 read, Boolean read430) at System.Net.Mail.SmtpReplyReaderFactory.Read430s(SmtpReplyReader caller, Boolean one430) at System.Net.Mail.SmtpReplyReaderFactory.Read430(SmtpReplyReader caller) at System.Net.Mail.CheckCommand.Send(SmtpConnection conn, String& response) at System.Net.Mail.MailCommand.Send(SmtpConnection conn, Byte[] command, MailAddress from, Boolean allowUnicode) at System.Net.Mail.SmtpTransport.SendMail(MailAddress sender, MailAddressCollection recipients, String deliveryNotify, Boolean allowUnicode, SmtpFailedRecipientException& exception) at System.Net.Mail.SmtpClient.Send(MailMessage message)
It appears that the Using Statements are causing the connection to close too early....
Anyone else had similar experience/tips on solution?
I've reverted to the old code, but it is better practice to wrap in using statements, right?

Related

aws simple email service not working with godaddy hosting asp.net

I was earlier using godaddy email services to send emails from my web application in asp.net. But now I moved to aws ses as it is fast.
The thing is in development environment(Local) aws email is working fine and emails are going but when I am deploying it in godaddy server then no email is going. Do I need to do any settings at godaddy server level or it is my code fault? My website is in shared hosting environment. Is it the reason.
Is this related to MX records?
Here is my code
string UserName = ConfigurationManager.AppSettings["UserName"];
string EmailFrom = ConfigurationManager.AppSettings["EmailFrom"];
string EmailFromDisplayName = ConfigurationManager.AppSettings["EmailFromDisplayName"];
string EmailFromPwd = ConfigurationManager.AppSettings["EmailFromPwd"];
string EmailBcc = ConfigurationManager.AppSettings["EmailBcc"];
bool EmailIsSSL = Convert.ToBoolean(ConfigurationManager.AppSettings["EmailIsSSL"]);
int EmailPort = Convert.ToInt32(ConfigurationManager.AppSettings["EmailPort"]);
string EmailHost = ConfigurationManager.AppSettings["EmailHost"];
//Create the msg object to be sent
MailMessage mailMessage = new MailMessage();
//Default email message
mailMessage.Bcc.Add(EmailBcc);
//Configure the address we are sending the mail from
MailAddress address = new MailAddress(EmailFrom, EmailFromDisplayName);
mailMessage.From = address;
//Loop all to recepients
foreach(string emailTo in toAddress)
{
mailMessage.To.Add(emailTo);
}
//Loop to add all Bcc addresses...
foreach (string emailBcc in bccAddress)
{
mailMessage.Bcc.Add(emailBcc);
}
//Loop to add all CC addresses...
foreach (string emailCc in ccAddress)
{
mailMessage.CC.Add(emailCc);
}
//Add attachments...
foreach (string filePathWithName in relativeFilePathsToBeAttached)
{
if (File.Exists(System.Web.HttpContext.Current.Server.MapPath(filePathWithName)))
{
Attachment data = new Attachment(
System.Web.HttpContext.Current.Server.MapPath(filePathWithName),
MediaTypeNames.Application.Octet);
// your path may look like Server.MapPath("~/file.ABC")
mailMessage.Attachments.Add(data);
}
}
mailMessage.Subject = mailSubject;
mailMessage.Body = mailBody;
mailMessage.IsBodyHtml = IsBodyHtml;
//Configure an SmtpClient to send the mail.
SmtpClient client = new SmtpClient();
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.EnableSsl = EmailIsSSL;
client.Host = EmailHost;
client.Port = EmailPort;
//Setup credentials to login to our sender email address ("UserName", "Password")
//NetworkCredential credentials = new NetworkCredential(EmailFrom, EmailFromPwd);
NetworkCredential credentials = new NetworkCredential(UserName, EmailFromPwd);
client.UseDefaultCredentials = true;
client.Credentials = credentials;
if (ConfigurationManager.AppSettings["IsMailEnabled"].ToString() == "true")
{
client.Send(mailMessage);
}
I am getting this error on server
Failure sending mail.System.IO.IOException: Unable to read data from the transport connection: net_io_connectionclosed. at System.Net.Mail.SmtpReplyReaderFactory.ProcessRead(Byte[] buffer, Int32 offset, Int32 read, Boolean readLine) at System.Net.Mail.SmtpReplyReaderFactory.ReadLines(SmtpReplyReader caller, Boolean oneLine) at System.Net.Mail.SmtpReplyReaderFactory.ReadLine(SmtpReplyReader caller) at System.Net.Mail.SmtpConnection.GetConnection(ServicePoint servicePoint) at System.Net.Mail.SmtpTransport.GetConnection(ServicePoint servicePoint) at System.Net.Mail.SmtpClient.GetConnection() at System.Net.Mail.SmtpClient.Send(MailMessage message) at System.Net.Mail.SmtpClient.Send(MailMessage message) at TestCookie.ExecuteSendEmail(String mailBody, String mailSubject, List1 toAddress, List1 bccAddress, List1 ccAddress, List1 relativeFilePathsToBeAttached, Boolean IsBodyHtml)
The issue was with port number. I was using 587 and 25 and it is not working. But when I used 2587 and it worked for me. I don't know how. If someone can explain then that will help.

How can I sendEmail to two addresses at once?

I'm new to ASP.NET, so I hope I'm providing the right context and information here.
I have a (pre-existing) form that looks like this:
protected void sendEmail(object sender, EventArgs e)
{
try
{
this.recaptcha.Validate();
if (this.recaptcha.IsValid == true)
{
lblResult.Visible = false;
String from = "donotreply#website.com";
String to = "test2#website.com";
String to2 = "test1#website.com";
MailMessage mail = new MailMessage();
mail.From = new MailAddress(from);
mail.To.Add(new MailAddress(to));
mail.To.Add(new MailAddress(to2));
mail.IsBodyHtml = true;
SmtpClient smtp = new SmtpClient("localhost");
smtp.Send(mail);
}
Based on what I've googled, using mail.To.Add twice is the proper way to send the resulting mail to two separate addresses -- but unfortunately, I've had no luck at all. Nor does separating two addresses using a comma or semicolon work.
What is the proper way to do this?

Unable to send mail if one mail not present with ASP

I've written code for sending a newsletter, all is working fine, but there is a problem if one of the email addresses in the list, doesn't exit or the domain does not exist.
In this case the script stops immediately and the sending of the mail list is not finished.
Here is the part of the code I want to modify.
public static void SendMessage(String sender, String recipient, String message, String object)
{
try
{
MailMessage mail = new MailMessage(sender, recipient);
mail.Subject = object;
mail.IsBodyHtml = true;
mail.Body = message;
SmtpClient smtp = new SmtpClient();
smtp.Host = "my.smtp.com";
smtp.Send(mail);
}
catch (Exception e)
{ throw new Exception("AdminEmail - SendMessage >> recipient: " + recipient + " - generic error: " + e.Message); }
}
Hope somone can help me, thank you very much!
Welcome to SO.
From what I can infer from your description your are not handling the exception that is thrown by SendMessage.
Handle the exception in the caller method. Or do a dirty fix as shown below...
This is not a real fix. But will help you understand the issue...You have to determine in your calling method what to do if SendMessage throws an exception.
public static void SendMessage(String sender, String recipient, String message, String object)
{
try
{
MailMessage mail = new MailMessage(sender, recipient);
mail.Subject = object;
mail.IsBodyHtml = true;
mail.Body = message;
SmtpClient smtp = new SmtpClient();
smtp.Host = "my.smtp.com";
smtp.Send(mail);
}
catch (Exception e)
{
//Just log error and continue to process
}
}

configuration of asp.net mailmessage

Can someone help me pls. I am ready to deploy my web application. I have a contact form that i want users to send me a message. Ive created the smtp when i click on submit, i get the error message cannot be sent.
The application is still on my local machine maybe thats why. But i just want to know if this code is good for my form:
Imports System.Net.Mail
Partial Class contact
Inherits System.Web.UI.Page
Protected Sub CustomValidator1_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs) Handles CustomValidator1.ServerValidate
If txtComments.Text.Length > 300 Then
args.IsValid = False
Else
args.IsValid = True
End If
End Sub
Protected Sub Wizard1_FinishButtonClick(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.WizardNavigationEventArgs) Handles Wizard1.FinishButtonClick
SendMail(txtEmail.Text, txtComments.Text)
End Sub
Private Sub SendMail(ByVal from As String, ByVal body As String)
Dim mailServerName As String = "SMTP.relay-hosting.secureserver.net"
Dim message As MailMessage = New MailMessage(from, "collins#collinsegbe.com", "feedback", body)
Dim mailClient As SmtpClient = New SmtpClient
mailClient.Host = mailServerName
mailClient.Send(message)
message.Dispose()
End Sub
End Class
The error is indicated on this line of code: mailClient.Send(message)
I will appreciate help from anyone
protected void Button9_Click(object sender, EventArgs e)
{
{
var fromAddress = new MailAddress("rusty109.stud#gmail.com");
var toAddress = new MailAddress(TextBox13.Text);
const string fromPassword = "commando1";
string subject = TextBox14.Text;
string body = TextBox12.Text;
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, fromPassword),
Timeout = 20000
};
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body
})
{
smtp.Send(message);
}
}
}
my old code when i wanted to email, you can use the gmail account if you wish, nothing in it... was set up to use this code :)
using System.Net.Mail;
using System.Net;
You need to add the username and password for the SMTP server by setting the SmtpClient's Credential property to an instance of the NetworkCredential class.

ASP.NET won't send email and no error message, weird!

I tried to send an email using this class below, but no success, no error message, the page just executed very fast, any problem with this class?
public bool mailSender(string strSubject, string strFrom, string strFromName, string strTo, string strBody)
{
SmtpClient smtpClient = new SmtpClient();
MailMessage message = new MailMessage();
try
{
MailAddress fromAddress = new MailAddress(strFrom, strFromName);
smtpClient.Host = ConfigurationManager.AppSettings["smtpServer"];
smtpClient.Port = 25;
smtpClient.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["smtpUsername"], ConfigurationManager.AppSettings["smtpPassword"]);
message.From = fromAddress;
message.To.Add(strTo);
message.Subject = strSubject;
message.IsBodyHtml = false;
message.Body = strBody;
smtpClient.Send(message);
return true;
}
catch
{
return false;
}
}
Your try/catch block is deliberately throwning away any error message. Remove that and see what you get.
piggy backing of what bruce said, do this:
try
'your code here'
catch ex As Exception
Response.Write(ex.Message)
end try
One thing I have noticed, especially when running in the debugger, is that the SmtpClient doesn't seem to actually send the mail until it gets disposed. At least, I often see the messages going out when I shutdown the debugger rather than at the time the mail is actually supposed to be sent.

Resources