I'm using the following code to open a text file and send emails to the people listed and changing the subject to include their ids. The issue i'm having is that the first time through testing I stopped the debugger on the subject line. The next thing I know I'm getting the test email. How could the code continue to execute even when I stopped the debugger?
Here is my code:
protected void btnTest_Click(object sender, EventArgs e)
{
string sFilePath = #"C:\email\" + ddlYear.SelectedItem.Value + "-" + ddlMonth.SelectedItem.Value + "_Num.txt";
using (TextFieldParser parser = new TextFieldParser(sFilePath))
{
parser.TextFieldType = FieldType.FixedWidth;
parser.SetFieldWidths(4, -1);
int iRowCnt = 1;
while (!parser.EndOfData)
{
string[] sCurrRow = parser.ReadFields();
try
{
System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage("test#test.com", sCurrRow[1].ToString());
message.Subject = txtSubject.Text + " - ID #" + sCurrRow[0].ToString() ;
message.IsBodyHtml = Convert.ToBoolean(ddlFormat.SelectedValue);
message.Body = txtMsg.Text;
System.Net.Mail.SmtpClient mailClient = new System.Net.Mail.SmtpClient();
mailClient.Host = "testSMTP.test.com";
mailClient.Credentials = new System.Net.NetworkCredential("TestSMTP", "TESTING"); //Username and password changes
mailClient.Send(message);
this.InsEmailDB(iRowCnt, iRowCnt, sCurrRow[1].ToString());
iRowCnt++;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
Stopping the debugger doesn't terminate the program, it just stops "watching" it-- the program will still run to completion.
Debugging as it's name suggests, is to error free the application. It only show you how it is executing. Stopping debug doesn't mean stopping application. And I think receiving test mail isn't big issue.
Related
I have a mailer and here is the code:
private static int i=0;
protected void btnSubmit_Click(object sender, EventArgs e)
{
++i; //i want to increment this variable
{
SendHTMLMail();
}
void SendHTMLMail()
{
StreamReader reader = new StreamReader(Server.MapPath("~/one.html"));
string readFile = reader.ReadToEnd();
string myString = "";
myString = readFile;
MailMessage Msg = new MailMessage();
Msg.From = new MailAddress(txtUsername.Text);
Msg.To.Add(txtTo.Text);
Msg.Subject = txtSubject.Text;
Msg.Body = myString.ToString();
Msg.IsBodyHtml = true;
if (fuAttachment.HasFile)
{
string FileName = Path.GetFileName(fuAttachment.PostedFile.FileName);
Msg.Attachments.Add(new Attachment(fuAttachment.PostedFile.InputStream, FileName));
}
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com";
smtp.Port = 587;
smtp.UseDefaultCredentials = false;
smtp.Credentials = new System.Net.NetworkCredential(txtUsername.Text, txtpwd.Text);
smtp.EnableSsl = true;
smtp.Send(Msg);
Msg = null;
ClientScript.RegisterStartupScript(GetType(), "alert", "alert('Email sent.');", true);
// Request both failure and success report
Msg.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure | DeliveryNotificationOptions.OnSuccess;
int emailsSent = 0;
try
{
Console.WriteLine("start to send email ...");
smtp.Send(Msg);
emailsSent++;
Console.WriteLine("email was sent successfully!");
}
catch (Exception ex)
{
Console.WriteLine("failed to send email with the following error:");
Console.WriteLine(ex.Message);
}
}
}
in the above code, i have a variable 'i' and i want to increment it every time i send the mail. Now the problem i am facing is that 'i' is getting incremented only when i am sending mail again and again when my aspx page in localhost is opened. As soon as i close my aspx page, re-opens it and send the mail again, then the variable 'i' is again getting incremented to one and not to say 4 or 5.
Behavior changes where you put this code. If it's in ASPX pages, you'll loose static data whenever runtime recompile that page. If it's in DLL files, you'll loose values whenever application/IIS Pool recycles. You need to save final values into a persistent store (ie Database). Next time you need them, you must retrieve from DB, increment it then save again.
Be careful, web applications are multi-thread and static variables are not thread safe. If two threads modify same variable at the same time you'll run into chaos. Use locking mechanism to access static variables in multi-threaded applications.
You need to define a separate static class for it- (because if you hit refresh / reload page in asp.net life cycle the entire page gets reloaded along with the objects.)
Define a static class (or a non static class with its constructor called) with variable/property to be incremented every time you send mail.
public static class Mail
{
private static int mailCount;
public static void MailSent()
{
mailCount++;
}
public static int GetMailCount()
{
return mailCount;
}
}
Now in your button click use the static methods to increment and retrieve of mailCount-
protected void btnSubmit_Click(object sender, EventArgs e)
{
Mail.MailSent(); // increments every time you send mail
// to check how many mails sent in debug console
System.Diagnostics.Debug.WriteLine(Mail.GetMailCount());
//... YOU MAILING CODE
}
My code works within a local network and I know it will not work outside of the local network as I am using Dns.GetHostEntry to resolve the IP address to hostname and thats fine...
But my if statement is not working, I am getting error "No Host Found" message when trying to resolve hostname from different subnet.
I thought my if statement would stop this error but its not working, can someone help please or tell me how to fix it, code below...
public partial class _Default : System.Web.UI.Page
{
//public string IPaddr1 { get; private set; }
string serviceDesk = "eg#mail.co.uk";
string emailSubject = "MyPc";
string IPaddr = "";
string deviceName = "";
protected void Page_Load(object sender, EventArgs e)
{
getIP();
}
protected void getIP()
{
if (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDER_FOR"] != null)
{
IPaddr = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDER_FOR"].ToString();
}
if (HttpContext.Current.Request.UserHostAddress.Length != 0)
{
IPaddr = HttpContext.Current.Request.UserHostAddress;
deviceName = Dns.GetHostEntry(IPAddress.Parse(IPaddr)).HostName;
}
if (HttpContext.Current.Request.UserHostAddress.Length != 0)
{
deviceName = "Device name could be found";
}
Label1.Text = "IP Address: " + " " + IPaddr;
Label2.Text = "PC Name: " + " " + deviceName;
}
private void EmailVerificationRequest(string recepientEmail, string subject)
{
try
{
using (MailMessage mailMessage = new MailMessage())
{
StringBuilder sbEmailBody = new StringBuilder();
sbEmailBody.Append("IP address " + IPaddr + "<br/>");
sbEmailBody.Append("Hostname " + " " + deviceName);
mailMessage.From = new MailAddress(ConfigurationManager.AppSettings["FromEmail"]);
mailMessage.Subject = subject;
mailMessage.Body = sbEmailBody.ToString();
mailMessage.IsBodyHtml = true;
mailMessage.To.Add(new MailAddress(recepientEmail));
SmtpClient smtp = new SmtpClient();
smtp.Host = ConfigurationManager.AppSettings["Host"];
smtp.Port = Convert.ToInt32(ConfigurationManager.AppSettings["Port"]);
smtp.EnableSsl = Convert.ToBoolean(ConfigurationManager.AppSettings["EnableSsl"]);
System.Net.NetworkCredential NetworkCred = new System.Net.NetworkCredential();
NetworkCred.UserName = ConfigurationManager.AppSettings["UserName"];
NetworkCred.Password = ConfigurationManager.AppSettings["Password"];
if (string.IsNullOrWhiteSpace(NetworkCred.UserName))
{
smtp.UseDefaultCredentials = true;
}
else
{
smtp.Credentials = NetworkCred;
smtp.UseDefaultCredentials = false;
}
smtp.Port = int.Parse(ConfigurationManager.AppSettings["Port"]);
try
{
smtp.Send(mailMessage);
}
catch (SmtpException e)
{
}
}
}
catch
{
}
}
protected void Button1_Click(object sender, EventArgs e)
{
EmailVerificationRequest(serviceDesk, emailSubject);
Response.Redirect("~/message.aspx");
}
}
From the MSDN Documentation:
If the host name could not be found, the SocketException exception is returned with a value of 11001 (Windows Sockets error WSAHOST_NOT_FOUND). This exception can be returned if the DNS server does not respond. This exception can also be returned if the name is not an official host name or alias, or it cannot be found in the database(s) being queried.
Therefore, I suspect your code isn't getting as far as the third if condition because an exception is being thrown by the call to GetHostEntry(), which you're seeing as the 'error "No Host Found" message'.
The most straightforward way to deal with this is to use a try...catch block to catch the specific exception and handle it, something such as:
try
{
deviceName = Dns.GetHostEntry(IPAddress.Parse(IPaddr)).HostName;
}
catch (SocketException)
{
deviceName = "Device name could be found";
}
This says that if a SocketException occurs during the call to GetHostEntry(), the code is to jump to the catch block, rather than the exception stopping your application.
Note that this assumes that any SocketException means that the IP address wasn't found, but it could mean that the DNS server wasn't contactable, or some other error.
MSDN has quite a lot on exception handling and how try...catch blocks work.
Hope this helps
Before you get a value from a dictionary, you must check if the dictionary contains the key you pass. You achieve this by calling "Contains" method.
if (HttpContext.Current.Request.ServerVariables.Contains("HTTP_X_FORWARDER_FOR"))
{
// Your Code...
}
If you retrieve the content of a dictionary directly and the key you are requesting doesn't exist in the dictionary pairs, the dictionary doesn't return null. Instead, it throws KeyNotFoundException.
I am attaching a pdf file exported from crystal report. When I use this on development PC it works fine. However when I try on clients PC it gives me an exception
system.io.ioexception the process cannot access the file because it is being used by another process
Here's my code:
private void button1_Click(object sender, EventArgs e)
{
try
{
printbanqoute.ExportToDisk(ExportFormatType.PortableDocFormat, "G:\\" + filename);////For Client PC
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
MailMessage mm = new MailMessage();
try
{
string toemail = BLDashboard.email;
string custnm = BLDashboard.custname;
mm.From = new MailAddress("operations#kaem.in", "Kashif Ahhmed");
mm.To.Add(new MailAddress(toemail, custnm));
mm.IsBodyHtml = true;
string name = BLDashboard.custname;
mm.Subject = "Qoutation ";
String Body = "<div>Hello " + name + ",<br> Thank you for considering us for your next Party/Event, here is the qoute for the Party/Event.<br> If any queries you can reach us at 6096464445. <br> Thank You</div>";
mm.Body = Body;
mm.Attachments.Add(new Attachment("G:\\" + filename));///For Cleint PC
SmtpClient sc = new SmtpClient("smtp.kaem.in");
sc.Credentials = new NetworkCredential("operations#kaem.in", "******");
sc.Send(mm);
MessageBox.Show("Email successfully sent to " + toemail);
}
catch (Exception e1)
{
MessageBox.Show("Unable to send email due to following error:\n\n" + e1.Message, "Email send error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
mm.Dispose();//// Later Added this line
}
}
After searching I added
finally
{
mm.Dispose();//// Later Added this line
}
Now it just gave me error no exception.
I tried Disabling and trying, but same issue.
Here's the exception that I am getting:
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 don't want the user to wait for page completing the sending processes, so I'm thought of using SendAsync in ASP.NET 3.5. But for after debuging, I found that the Main Thread still waits.
Main: Call send email function...
mailSend: Configuring....
mailSend: setting up incorrect port....
mailSend: Attempt now to send....
mailSend: End of Line
Main: Email Function call finish.
Main: Proccess Complete!
mailComp: Sending of mail failed, will try again in 5 seconds...
mailComp: Retrying...
mailComp: Send successful!
mailComp: End of Line
Now the I placed incorrect port setting so the first email fails, and test to see if the second time it will be successful. Even with the correct port, the page still waits. Only after mailComp function is finish is when the Page is finally posted. Is this some limitation to SendAsyn?
And here some code, not sure if this will be helpful.
protected void btnReset_Click(object sender, EventArgs e)
{
try
{
DataContext db = new DataContext();
var query = from u in db.Fish
where u.Username == txtUsername.Text & u.Email == txtEmail.Text
select new { u.Username, u.Email };
if (query.Count() != 0)
{
User user = new User();
String token = user.requestPasswordReset(txtUsername.Text);
String URL = Request.Url.AbsoluteUri.ToString() + "?token=" + token;
String body = "Reseting you password if you \n" + URL + "\n \n ";
Untilty.SendEmail(txtEmail.Text, "Reseting Password", body);
litTitle.Text = "Message was sent!";
litInfo.Text = "Please check your email in a few minuets for further instruction.";
viewMode(false, false);
}
else
{
litCannotFindUserWithEmail.Visible = true;
}
}
catch (Exception ex)
{
Debug.Write("Main: Exception: " + ex.ToString());
litInfo.Text = "We are currently having some technically difficulty. Please try again in a few minuets. If you are still having issue call us at 905344525";
}
}
///
public static class Utility
///
public static void SendEmail(string recipient, string subject, string body)
{
MailMessage message = new MailMessage();
message.To.Add(new MailAddress(recipient));
message.From = new MailAddress(fromaddress, "Basadur Profile Website");
message.Subject = subject;
message.Body = body;
Send(message);
}
private static void Send(MailMessage msg)
{
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com";
smtp.Credentials = new System.Net.NetworkCredential(fromaddress, mailpassword);
smtp.EnableSsl = true;
Debug.WriteLine("mailSend: setting up incorrect port....");
smtp.Port = 5872; //incorrect port
smtp.SendCompleted += new SendCompletedEventHandler(smtp_SendCompleted);
smtp.SendAsync(msg, msg);
}
static void smtp_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
var msg = (MailMessage)e.UserState;
if (e.Error != null)
{
System.Threading.Thread.Sleep(1000 * 5);
try
{
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com";
smtp.Credentials = new System.Net.NetworkCredential(fromaddress, mailpassword);
smtp.EnableSsl = true;
smtp.Port = 587;
smtp.Send(msg);
}
catch (Exception ex)
{
Debug.WriteLine("mailComp: Failed for the second time giving up.");
}
}
}
In .NET 4.5.2, a method was added for scheduling tasks in the background, independent of any request: HostingEnvironment.QueueBackgroundWorkItem().
HostingEnvironment.QueueBackgroundWorkItem() is in the System.Web.Hosting namespace.
The remarks in the documentation say:
Differs from a normal ThreadPool work item in that ASP.NET can keep
track of how many work items registered through this API are currently
running, and the ASP.NET runtime will try to delay AppDomain shutdown
until these work items have finished executing.
Meaning, you can fire off a task in a fire-and-forget manner with a greater confidence in it not being terminated when the app domain recycles.
Usage is like:
HostingEnvironment.QueueBackgroundWorkItem(cancellationToken =>
{
try
{
// do work....
}
catch(Exception)
{
//make sure nothing can throw in here
}
});
These days you can use a Task to dispatch work to the thread pool. Just use
Task.Run(()=> Untilty.SendEmail(txtEmail.Text, "Reseting Password", body));
The debugger seems to force things to be single threaded. If you step through, you may find that you end up jumping between two different files, as each step moves a different thread.
Try to add some logging in there and run without debugging.
Using the below code you can send async emails in asp.net with SmtpClient.
ThreadPool.QueueUserWorkItem(callback =>
{
var mailMessage = new MailMessage
{
...
};
//if you need any references in handlers
object userState = new ReturnObject
{
MailMessage = mailMessage,
SmtpClient = smtpServer
};
smtpServer.SendCompleted += HandleSmtpResponse;
smtpServer.SendAsync(mailMessage, userState);
});
Use threading:
// Create the thread object, passing in the method
// via a ThreadStart delegate. This does not start the thread.
Thread oThread = new Thread(new ThreadStart(SendMyEmail));
// Start the thread
oThread.Start();
Here is the source, it has a full threading tutorial.