I'm attempting to learn about generating an email with attachment(s) using C# CodeBehind. I would like the web page to use the FileUpload control or something similar to select the file on the network.
I get a "Could not find a part of the path 'E:\Web Sites\myNet\Ztest\TrailerPics\'."
I'm wondering if I'm on the right path... or if there is a better approach.
Thx for any help ~j
Here is my code:
protected void Button1_Click(object sender, EventArgs e)
{
//Get file names from the fileUpload control
var fileName = Path.GetFileName(FileUpload1.PostedFile.FileName);
var fileName2 = Path.GetFileName(FileUpload2.PostedFile.FileName);
var fileName3 = Path.GetFileName(FileUpload3.PostedFile.FileName);
//Code block to send email with keyed data
try
{
MailMessage mail = new MailMessage();
mail.From = new MailAddress("DoNotReply#smiley.com");
mail.To.Add("guy.smiley#sesamestreet.com");
mail.Subject = ("IMG");
mail.IsBodyHtml = true;
var client = new SmtpClient("mailout.smiley.com", 25);
string htmlBody;
htmlBody = string.Format("Email Testing for attaching an image");
mail.Body = htmlBody;
//Create the instance of attachments by using the mapped path concatenated with the file name
Attachment addon = new Attachment(Server.MapPath("~/TrailerPics/" + fileName));
Attachment addon2 = new Attachment(Server.MapPath("~/TrailerPics/" + fileName2));
Attachment addon3 = new Attachment(Server.MapPath("~/TrailerPics/" + fileName3));
//Add the attachments as long as the fileUpload control has a file selected
if (FileUpload1.PostedFile.FileName != "")
{
mail.Attachments.Add(addon);
}
if (FileUpload2.PostedFile.FileName != "")
{
mail.Attachments.Add(addon2);
}
if (FileUpload3.PostedFile.FileName != "")
{
mail.Attachments.Add(addon3);
}
//Send mail
client.Send(mail);
//Notify that email was sent
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "alertMessage", "alert('Email Sent!')", true);
//Close all connections to the files
if (FileUpload1.PostedFile.FileName != "")
{
addon.Dispose();
}
if (FileUpload2.PostedFile.FileName != "")
{
addon2.Dispose();
}
if (FileUpload3.PostedFile.FileName != "")
{
addon3.Dispose();
}
}
catch(Exception ex)
{
//inform user that the email failed
errorLabel.Text = "Something went wrong with the email : " + ex.Message;
}
}
Related
I know this question that had been asked before but didn't find an appropriate solution to it yet! I hosted my website a few days ago. Everything works normally in my website a part of my contact form that it doesn't work!
The contact form itself doesn't show any errors whatsoever, in fact when I send the details I still get the label message that confirms of sending process, but nothing comes into my email.
The strange thing is when I talked to my host provider, he says to me that there is nothing wrong with my script and they didn't block any port.
I also ran the contact page and done the same process by filling all required fields and it works properly.Any help would much appreciated!
My code :
namespace contact
{
public partial class ContactUs : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager.ScriptResourceMapping.AddDefinition("jquery", new
ScriptResourceDefinition
{
Path = "~/scripts/jquery-1.9.1.js"
});
}
protected void btnSub_Click1(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(2000);
try
{
if (Page.IsValid)
{
MailMessage mail = new MailMessage();
mail.From = new MailAddress(txtEmail.Text);
mail.To.Add("myemailaddress");
mail.Subject = txtSubject.Text;
mail.Body = "<b> Sender Name: </b>" + txtName.Text + "
<br/>"
+ "<b> Sender Email: </b>" + txtEmail.Text + "<br/>"
+ "<b> Sender Comment: </b>" + txtMessage.Text;
mail.IsBodyHtml = true;
SmtpClient smtpClient = new
SmtpClient("company's mail", 587);
smtpClient.EnableSsl = true;
smtpClient.Credentials = new
System.Net.NetworkCredential("myemailaddress","password");
smtpClient.Send(mail);
lblmsg.Text = "Thank you for contacting us";
txtName.Enabled = false;
txtEmail.Enabled = false;
txtSubject.Enabled = false;
txtMessage.Enabled = false;
btnSub.Enabled = false;
}
}
catch (Exception ex)
{
lblmsg.Text = "An unexpected error has occured! " + ex.Message;
}
}
}
I am trying to send a mail via goDaddy mail server. The mail is being sent (I am receiving it in my mailbox) but the catch block is executing and landing me to the contact page with querystring msg as "fail"
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["username"] != null && Request.QueryString["email"] != null && Request.QueryString["msg"] != null)
{
try
{
string name = Request.QueryString[0];
string email = Request.QueryString[1];
string msg = Request.QueryString[2];
SmtpClient smtp = new SmtpClient("relay-hosting.secureserver.net", 25);
//smtp.EnableSsl = false;
smtp.Send("feedback#solutionpoint98.com", "b.soham1991#gmail.com", "feedback", "Name:" + name + "\n e-mail:" + email + "\n Subject:" + msg);
Response.Redirect("contact.html?msg=success");
}
catch(Exception ex)
{
Response.Redirect("contact.html?msg=fail");
}
}
else
{
Response.Redirect("contact.html");
}
}
If the mail is being sent, shouldn't it redirect to "contact.html?msg=success"?
The problem is that your first Response.Redirect() is actually throwing a ThreadAbortException. This is due to the fact that .Redirect internally calls the Response.End method, prematurely ending the Response in this case.
The correct way to do this is to use the overloaded Response.Redirect(string url, bool endResponse), which allows you to suppress the internal call to Response.End by setting endResponse to false ... which will prevent this error from being thrown.
This is all covered in this MS support article: http://support.microsoft.com/kb/312629/EN-US/
Just modify your code to look like this:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["username"] != null && Request.QueryString["email"] != null && Request.QueryString["msg"] != null)
{
try
{
string name = Request.QueryString[0];
string email = Request.QueryString[1];
string msg = Request.QueryString[2];
SmtpClient smtp = new SmtpClient("relay-hosting.secureserver.net", 25);
//smtp.EnableSsl = false;
smtp.Send("feedback#solutionpoint98.com", "b.soham1991#gmail.com", "feedback", "Name:" + name + "\n e-mail:" + email + "\n Subject:" + msg);
Response.Redirect("contact.html?msg=success", false);
}
catch(Exception ex)
{
Response.Redirect("contact.html?msg=fail", false);
}
}
else
{
Response.Redirect("contact.html", false);
}
}
I hope you can help me with this problem. When I click a Email button, it takes few seconds to process before sending successfully. I need to put process image on but how to implement with "while" loop for processing.
Here is code: i think i should implement with client.Send(msg); for processing. How does it work? I will appreciate your example code. Thanks! (I am using C# and WPF)
private void BtnSendEmailClick(object sender, RoutedEventArgs e)
{
SmtpClient client = null;
MailMessage msg = null;
try
{
msg = new MailMessage
{
From = new MailAddress("me#hotmail.com", "Me Hotmail")
};
msg.To.Add(txtEmailAddress.Text);
msg.Priority = MailPriority.High;
msg.Subject = "Blah blah";
msg.Body =
"<!DOCTYPE html><html lang='en' xmlns='http://www.w3.org/1999/xhtml'>" +
"<head> </head>" +
"<body>" +
"<h3>Message</h3>" +
"<p>" + lblEmailMessage.Content + "</p>" +
"</body>" +
"</html>";
msg.IsBodyHtml = true;
client = new SmtpClient
{
Host = "smtp.live.com",
Port = 25,
EnableSsl = true,
UseDefaultCredentials = false,
Credentials = new NetworkCredential("me#hotmail.com", "password"),
DeliveryMethod = SmtpDeliveryMethod.Network
};
//how to implement while loop for processing
client.Send(msg);
lblMessage.Content = "Successfully sent to your Mail!";
}
catch (Exception ex)
{
lblMessage.Content = ex.Message;
}
}
You will need to return instantly, and use a BackgroundWorker to send the email. Once it is finished, you can use the Dispatcher to notify the GUI. See http://msdn.microsoft.com/en-us/magazine/cc163328.aspx for more details.
See also How to use WPF Background Worker.
Are you wanting to display an image to indicate that the program is doing something (progress indicator)?
In that case you need to do the work of sending the email on a separate thread. You can do this in several ways. The easiest (if you are using .NET 4) is to use the await and async keywords. Simply display the image before starting your work. You'll need to extract the code that actually sends the email into a new method also. Like this:
private void BtnSendEmailClick(object sender, RoutedEventArgs e)
{
// Display progress image
progressImage.Visibility = System.Windows.Visibility.Visible;
string errorMessage = await SendEmail();
if (errorMessage == null)
{
lblMessage.Content = "Successfully sent to your Mail!";
}
else
{
lblMessage.Content = errorMessage;
}
progressImage.Visibility = System.Windows.Visibility.Hidden;
}
private async Task<string> SendEmail()
{
try
{
var msg = new MailMessage
{
From = new MailAddress("me#hotmail.com", "Me Hotmail")
};
msg.To.Add(txtEmailAddress.Text);
msg.Priority = MailPriority.High;
msg.Subject = "Blah blah";
msg.Body =
"<!DOCTYPE html><html lang='en' xmlns='http://www.w3.org/1999/xhtml'>" +
"<head> </head>" +
"<body>" +
"<h3>Message</h3>" +
"<p>" + lblEmailMessage.Content + "</p>" +
"</body>" +
"</html>";
msg.IsBodyHtml = true;
var client = new SmtpClient
{
Host = "smtp.live.com",
Port = 25,
EnableSsl = true,
UseDefaultCredentials = false,
Credentials = new NetworkCredential("me#hotmail.com", "password"),
DeliveryMethod = SmtpDeliveryMethod.Network
};
//how to implement while loop for processing
client.Send(msg);
return "Successfully sent to your Mail!";
}
catch (Exception ex)
{
return ex.Message;
}
}
One final note: Be sure that you don't touch any UI components in your 'async' method as there is no guarantee that the code will be running on the UI thread. If you need more information returned from the async method you'll have to create a custom structure to contain the result and return it from that SendEmail() method.
I'm using the PasswordRecovery Control and can't send more then one email when there are multiple accounts with the same email. I get a MembershipUserCollection with Membership.FindUsersByEmail. I then loop through it in a foreach. My problem is if there is more then one user it only sends the last email. How can I get it to send an email for each account as it loops through? The delagate is called the correct number of times. Also, I know they are all going to the same email, but would like there to be one sent for each account.
Code Snip:
protected void PasswordRecovery1_SendingMail(object sender, MailMessageEventArgs e)
{
}
bool IsValidEmail(string strIn)
{
// Return true if strIn is in valid e-mail format.
return Regex.IsMatch(strIn, #"^([\w-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
}
protected void PasswordRecovery1_VerifyingUser(object sender, LoginCancelEventArgs e)
{
if (IsValidEmail(PasswordRecovery1.UserName))
{
// string uName = Membership.GetUserNameByEmail(PasswordRecovery1.UserName) ?? PasswordRecovery1.UserName;
MembershipUserCollection users = Membership.FindUsersByEmail(PasswordRecovery1.UserName);
if (users.Count < 1)
{
PasswordRecovery1.UserName = " ";
PasswordRecovery1.UserNameFailureText = "That user is not available"; }
else
{
foreach (MembershipUser user in users)
{
PasswordRecovery1.UserName = user.UserName;
PasswordRecovery1.SendingMail += PasswordRecovery1_SendingMail;
PasswordRecovery1.SuccessTemplateContainer.Visible = true;
}
}
}
else
{
PasswordRecovery1.UserName = " ";
PasswordRecovery1.UserNameFailureText ="Please enter a valid e-mail";
}
}
Figured it out ... the way I was originally doing it would not work, so I went semi-custom. I added an event handler on the submit button and edited the code as shown below. As you can see, I simply looped thorough the collection. Not the best I'm sure, but it works and is easy to understand.
The body of the email is created in a txt file with html formatting. Using the mailDefinition class allows me to have replacement strings, which simplifies the emails body creation.
It sends a separate email for each account to the same email. I could have put them all into a single email, but this is what they wanted ...
protected void PasswordRecovery1_SendingMail(object sender, MailMessageEventArgs e)
{
e.Cancel = true;
}
bool IsValidEmail(string strIn)
{
// Return true if strIn is a valid e-mail
return Regex.IsMatch(strIn, #"^([\w-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
}
protected void SubmitLinkButton_Click(object sender, EventArgs e)
{
if (IsValidEmail(PasswordRecovery1.UserName))
{
// Get user collection by shared email
MembershipUserCollection users = Membership.FindUsersByEmail(PasswordRecovery1.UserName);
if (users.Count < 1)
{
PasswordRecovery1.UserName = " ";
PasswordRecovery1.UserNameFailureText = "That user is not available";
}
else
{
// Loop and email each user in collection
foreach (MembershipUser user in users)
{
MembershipUser ur = Membership.GetUser(user.UserName);
DateTime now = DateTime.Now;
// Using MailDefinition instead of MailMessage so we can substitue strings
MailDefinition md = new MailDefinition();
// list of strings in password.txt file to be replace
ListDictionary replacements = new ListDictionary();
replacements.Add("<%UserName%>", ur.UserName);
replacements.Add("<%Password%>", ur.GetPassword());
// Text file that is in html format
md.BodyFileName = "absolute path to password.txt";
md.IsBodyHtml = true;
md.Priority = MailPriority.High;
md.Subject = "Email Subject Line - " + now.ToString("MM/dd - h:mm tt");
md.From = ConfigurationManager.AppSettings["FromEmailAddress"];
// Add MailDefinition to the MailMessage
MailMessage mailMessage = md.CreateMailMessage(ur.Email, replacements, this);
mailMessage.From = new MailAddress(ConfigurationManager.AppSettings["FromEmailAddress"], "Friendly Name");
SmtpClient m = new SmtpClient();
m.Host = "127.0.0.1";
m.Send(mailMessage);
PasswordRecovery1.UserName = user.UserName;
PasswordRecovery1.SendingMail += PasswordRecovery1_SendingMail;
}
}
}
else
{
PasswordRecovery1.UserName = " ";
PasswordRecovery1.UserNameFailureText = "Please enter a valid e-mail";
}
}
Now i fixed the filtering of file extension but i have a problem on "catch" it doesn't display any error message but good, it is not sending the email with wrong file type.
but my problem is here:
catch(Exception err)
{
Console.WriteLine(err.Message);
lblStatus.ForeColor = Color.Red;
lblFile.ForeColor = Color.Red;
lblStatus.Text = "There was an error occured while submitting your application";
lblFile.Text = " Accepts .doc, .docx and .pdf files only!";
return ;
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (fileUpload1.HasFile)
{
var fileName = Path.GetFileName(fileUpload1.PostedFile.FileName);
try
{
string strExtension = Path.GetExtension(fileName);
if (strExtension == ".docx" || strExtension == ".doc" || strExtension == ".pdf")
{
MailMessage myMessage = new MailMessage();
myMessage.To.Add(new MailAddress("someone#yahoo.com"));
myMessage.From = new MailAddress("me#gmail.com");
myMessage.Subject = txtSubject.Text;
myMessage.Body = "<html><body><br/><b>Sender Name:</b> " + txtName.Text.ToString() + "<br/><br/><b>Email:</b> " + txtEmail.Text.ToString() +
"<br/><br/><b>Contact Number:</b> " + txtContact.Text.ToString() + "<br/><br/><b>Subject</b> " + txtSubject.Text.ToString() +
"<br/><br/><b>CV Summary:</b><br/><br/>" + txtSummary.Text.ToString() + "</body></html>";
myMessage.IsBodyHtml = true;
myMessage.Attachments.Add(new Attachment(fileUpload1.PostedFile.InputStream, fileName));
SmtpClient mySmtp = new SmtpClient();
mySmtp.Host = "smtp.gmail.com";
mySmtp.Credentials = new System.Net.NetworkCredential("me#gmail.com", "mypassword");
mySmtp.EnableSsl = true;
mySmtp.Send(myMessage);
lblStatus.ForeColor = Color.Green;
lblStatus.Text = "We will contact you once you have been shortlisted to the position you are applying for. <br/> You may now close this window.";
txtName.Text = "";
txtEmail.Text = "";
txtSubject.Text = "";
txtSummary.Text = "";
txtContact.Text = "";
}
}
catch(Exception err)
{
Console.WriteLine(err.Message);
lblStatus.ForeColor = Color.Red;
lblFile.ForeColor = Color.Red;
lblStatus.Text = "There was an error occured while submitting your application";
lblFile.Text = " Accepts .doc, .docx and .pdf files only!";
return ;
}
}
}
protected void btnClear_Click(object sender, EventArgs e)
{
txtName.Text = "";
txtEmail.Text = "";
txtSubject.Text = "";
txtSummary.Text = "";
txtContact.Text = "";
}
Here is a nicer way to do it:
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (fileUpload1.HasFile) ;
{
var fileName = Path.GetFileName(fileUpload1.PostedFile.FileName);
try
{
string strExtension = Path.GetExtension(fileName);
if (strExtension != ".docx" || strExtension != ".doc" || strExtension != ".pdf")
{
lblFile.ForeColor = Color.Red;
lblFile.Text = "You can attach .doc,.docx and pdf files only";
lblStatus.ForeColor = Color.Red;
lblStatus.Text = "There was an error occured while sending your email. Please try again later.";
return;
}
MailMessage myMessage = new MailMessage();
myMessage.From = new MailAddress(txtEmail.Text);
myMessage.To.Add(new MailAddress("EMAIL#yahoo.com"));
myMessage.Subject = txtSubject.Text;
myMessage.Body = "<html><body><br/><b>Sender Name:</b> " + txtName.Text.ToString() + "<br/><br/><b>Email:</b> " + txtEmail.Text.ToString() +
"<br/><br/><b>Contact Number:</b> " + txtContact.Text.ToString() + "<br/><br/><b>Subject</b> " + txtSubject.Text.ToString() +
"<br/><br/><b>CV Summary:</b><br/><br/>" + txtSummary.Text.ToString() + "</body></html>";
myMessage.IsBodyHtml = true;
myMessage.Attachments.Add(new Attachment(fileUpload1.PostedFile.InputStream, fileName));
SmtpClient mySmtp = new SmtpClient();
mySmtp.Host = "smtp.gmail.com";
mySmtp.Credentials = new System.Net.NetworkCredential("EMAIL#gmail.com", "PASSWORD");
mySmtp.EnableSsl = true;
mySmtp.Send(myMessage);
lblStatus.ForeColor = Color.Green;
lblStatus.Text = "Email successfully sent! We will contact you as soon as you have been shortlisted for the position you are applying for.<br/> Thank You. You can close this window now. ";
txtName.Text = "";
txtEmail.Text = "";
txtSubject.Text = "";
txtSummary.Text = "";
txtContact.Text = "";
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
Basically, you only want to catch exceptions i.e. IO or mail sending failures.
This code will return if the extension is not a doc, docx or pdf and not call the send mail code.
Also, the myMessage.From() address must be a valid email address and the one that you supplied via your NetworkCredentials()
Here is a cut down version of the code that I have tested and verified that it is working:
protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile) ;
{
var fileName = Path.GetFileName(FileUpload1.PostedFile.FileName);
try
{
string strExtension = Path.GetExtension(fileName);
if (strExtension != ".docx" || strExtension != ".doc" || strExtension != ".pdf")
{
lblFile.ForeColor = Color.Red;
lblFile.Text = "You can attach .doc,.docx and pdf files only";
lblStatus.ForeColor = Color.Red;
lblStatus.Text = "There was an error occured while sending your email. Please try again later.";
return;
}
MailMessage myMessage = new MailMessage();
myMessage.To.Add(new MailAddress("OtherPersonsEmail#email.xyz"));
myMessage.From = new MailAddress("YourEmailAddress#gmail.com");
myMessage.Subject = "Test";
myMessage.Body = "asd asd as d";
myMessage.IsBodyHtml = true;
myMessage.Attachments.Add(new Attachment(FileUpload1.PostedFile.InputStream, fileName));
SmtpClient mySmtp = new SmtpClient();
mySmtp.Host = "smtp.gmail.com";
mySmtp.Credentials = new System.Net.NetworkCredential("YourEmailAddress#gmail.com", "YourPassword");
mySmtp.EnableSsl = true;
mySmtp.Send(myMessage);
}
catch(Exception ex)
{
lblStatus.ForeColor = Color.Red;
lblStatus.Text = ex.Message;
Console.WriteLine(ex.Message);
}
}
}