I am trying to make a program which sends emails to gmail server. I have completed my goal but now my next goal is to make a login form where I can login with different gmail accounts and send mails.
Here's the code for the Login form:
private void btnLogin_Click(object sender, EventArgs e)
{
User user = new User();
user.Email = textBoxEmail.Text;
user.Password = textBoxPassword.Text;
}
I want my user.Email and user.Password to be saved in the second form (main form), which is this:
private void btnSend_Click(object sender, EventArgs e) {
SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
MailMessage mail = new MailMessage();
mail.From = new MailAddress(/*I want user.Email to be here */,"Pavel Valeriu");
mail.To.Add(textBoxTo.Text);
mail.Subject = textBoxSubject.Text;
mail.Body = richText.Text;
SmtpServer.Port = 587;
SmtpServer.Credentials = new System.Net.NetworkCredential("pavelvaleriu24#gmail.com", /* and user.Password here */);
SmtpServer.EnableSsl = true;
SmtpServer.Send(mail);
MessageBox.Show("mail sent");
Close();
}
You can pass the value from the login form to the main form through the constructor
FormLogin:
private void btnLogin_Click(object sender, EventArgs e)
{
User user = new User();
user.Email = textBoxEmail.Text;
user.Password = textBoxPassword.Text;
FormMain frm = new FormMain (textBoxEmail.Text,textBoxPassword.Text);
frm.show();
}
FormMain:
public FormMain(string _email,string _password)
{
InitializeComponent();
Email = _email;
Password = _password;
}
string Email = sting.Empty;
string Password = string.Empty;
private void btnSend_Click(object sender, EventArgs e)
{
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
mail.From = new MailAddress(Email ,"Pavel Valeriu");
mail.To.Add(textBoxTo.Text);
mail.Subject = textBoxSubject.Text;
mail.Body = richText.Text;
SmtpServer.Port = 587;
SmtpServer.Credentials = new System.Net.NetworkCredential("pavelvaleriu24#gmail.com", Password );
SmtpServer.EnableSsl = true;
SmtpServer.Send(mail);
MessageBox.Show("mail Send");
Close();
}
EDIT :-
Include the default constructor for the Form
public FormMain()
{
InitializeComponent();
}
You can define a static class UserInformation with field static string Username & static string Password and in the first form
UserInformation.Username = "Sth";
and in second form
youTextBox.Text = UserInformation.Username.
Please read the http://msdn.microsoft.com/en-us/library/79b3xss3.aspx for more information
You could declare User class as public static on your first from:
public static class User...
...
private void btnLogin_Click(object sender, EventArgs e)
{
User.Email = textBoxEmail.Text;
User.Password = textBoxPassword.Text;
}
and on Main form access the User properties of Form1:
...
mail.From =Form1.User.Email
If security and design is no big issue and you 'just want it to work', you can go ahead and create a static class that can hold this information for you, like a data provider.
public static class LoginDataProvider
{
public static string Email {get; set;}
public static string Password {get; set;}
}
You can then go ahead and get save the information in your login form:
LoginDataProvider.Email = textBoxEmail.Text;
LoginDataProvider.Password = textBoxPassword.Text;
You can then go ahead and retrieve the information in the second form the same way.
If you are developing your appication in ASP.NET you can mention username and password in 'Session' other wise, you are moving with window application you can store credentials in global variables and access it any web forms
When you create the object of main form, when the user is authenticated, create a constructor to pass the user's email & password like
mainForm(string userEmail, string password) or mainForm(User user)
So
User user = new User();
user.Email = textBoxEmail.Text;
user.Password = textBoxPassword.Text;
If(user.Authenticate())
{
//call new MainForm(user)
Related
Can i send email without giving password on the NetworkCredentials? here is my code.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
MailMessage Myemail = new MailMessage();
private void btnsendemail_Click(object sender, EventArgs e)
{
SmtpClient myGmailserver = new SmtpClient("smtp.gmail.com",587);
myGmailserver.Credentials = new NetworkCredential("Email ID", "password");
Myemail.From = new MailAddress("Email ID");
Myemail.To.Add(tbTo.Text);
Myemail.Subject = tbsubject.Text;
Myemail.Body = tbmsg.Text;
myGmailserver.EnableSsl = true;
myGmailserver.Send(Myemail);
}
}
on the line myGmailserver.Credentials = new NetworkCredential("Email ID", "Password"); it asks for a password for that specific email what if i want to send email to someone and not knowing the password of that email how can i do it? please answer
Ok,I got my answer the password was for the credential not for the recipients..I got another thing to ask,I add the timer in my form and the timer is ticking.For example at "8:00pm" an email should be sent automatically to the manager sales for sale reporting.Someone help me with this please.
Yesterday, i had a task assigned by my senior to build a windows forms application in .net which looked like the image i attached. I did all the stuff regarding the sending process of the email application, but i stuck at one place, i couldn't figure out how to authenticate the password in the email form. The password must be of the same email, which was provided in the "From :" fields.
Here is the code behind of my form,
public partial class Form1 : Form
{
MailMessage message;
SmtpClient smtp;
public Form1()
{
InitializeComponent();
lbl_Error.Visible = false;
}
private void chk_Show_Password_CheckedChanged(object sender, EventArgs e)
{
if (chk_Show_Password.Checked == true)
txt_Password.PasswordChar= '\0';
else
txt_Password.PasswordChar='*';
}
private void btn_Send_Click(object sender, EventArgs e)
{
btn_Send.Enabled = false;
txt_Password.Text = "";
try
{
message = new MailMessage();
if(isValidEmail(txt_From.Text))
{
message.From = new MailAddress(txt_From.Text);
}
if (isValidEmail(txt_To.Text))
{
message.To.Add(txt_To.Text);
}
message.Body = txt_Details.Text;
//attributes for smtp
smtp = new SmtpClient("smtp.gmail.com");
smtp.Port = 587;
smtp.EnableSsl = true;
smtp.UseDefaultCredentials = false;
smtp.Credentials = new NetworkCredential("imad.majid90#gmail.com", "mypassword");
smtp.Send(message);
}
catch(Exception ex)
{
btn_Send.Enabled = true;
MessageBox.Show(ex.Message);
}
}
public bool isValidEmail(string email)
{
bool flagFalse = false; ;
if (!email.Contains('#'))
{
lbl_Error.Visible = true;
lbl_Error.ForeColor = System.Drawing.Color.Red;
lbl_Error.Text = "Email address must contain #";
return flagFalse;
}
return true;
}
}
Assuming you're using Gmail like the screenshot you posted shows, you can't check the password without trying to send the email.
My advice would be to attempt to send the email and catch an Exception if it fails. You can then show some indication that there has been an error, like a MessageBox or a Label on your form.
See the documentation for SmtpClient. The Send methods will throw an SmtpException if authentication fails.
EDIT:
Well, after seeing the additional code you posted, you are already handling any exceptions that are thrown, including an authentication failure. The user will see a MessageBox if the password is incorrect.
catch(Exception ex)
{
btn_Send.Enabled = true;
// MessageBox.Show(ex.Message);
lbl_Error.Text = "Invalid Username/Password";
}
Do a try catch for SmtpException and display the information to the user is unauthenticated.
http://msdn.microsoft.com/en-us/library/h1s04he7.aspx
It looks like your using Windows Authentication. It might be easier to fetch the user's email from Active Directory rather then prompting for credentials.
How to obtain email address with window authentication
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";
}
}
I am using SmtpClient to sent out email. I create some function in Mail class:
private void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
// Get the unique identifier for this asynchronous operation.
String token = (string)e.UserState;
if (e.Cancelled)
{
MailStatus = Status.CANCEL;
MailStatusMessage = token + " Send canceled.";
}
else if (e.Error != null)
{
MailStatus = Status.ERROR;
MailStatusMessage = token + " " + e.Error.ToString();
}
else
{
MailStatus = Status.SENT;
MailStatusMessage = "Mail sent.";
}
mailSent = true;
}
public void SentEmail()
{
client = new SmtpClient(Host, Port);
client.Credentials = new NetworkCredential(UserName, Password);
MailAddress from = new MailAddress(MerchantEmail, MerchantName);
MailAddress to = new MailAddress(CustomerEmail);
MailMessage message = new MailMessage(from, to);
message.Body = EmailSubjectTemplate();
message.BodyEncoding = System.Text.Encoding.UTF8;
message.Subject = EmailSubjectTemplate();
message.SubjectEncoding = System.Text.Encoding.UTF8;
client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
client.SendAsync(message, "Sending message.");
message.Dispose();
}
In a form I call the function, before closing the form, but when waiting for the response from the SendCompletedCallback, the this.Close() will be executed:
Mail mail = new Mail();
mail.SentEmail();
this.Close();
How can I stop the form from closing before I get a response from SendCompletedCallback?
There is little that you can do if your user decides to forcibly close its computer. (switch off, task kill or whatever).
However, you can wire the Form_Closing event and change the e.Cancel property inside the CloseEventArgs to true, perhaps with a messagebox informing your user of the pending operation.
First add to your Main form (or whatever you call it) a global var acting as a status flag:
private bool eMailSentPendingComplete = false;
then in your SentMail method add this line just after the client.SentAsync:
eMailSentPendingComplete = true;
reset it to false in the SendCompletedCallback
and in your Main Form wire the FormClosing event:
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
if(eMailSentPendingComplete == true)
{
DialogResult dr = MessageBox.Show("Pending email, do you wish to close?", MEssageBoxButtons.YesNo);
e.Cancel = (dr == DialogResult.Yes ? true : false);
}
}
also in the FormClosing event you can take a look to the property e.CloseReason for further optimizations.
Option1
public class Mail
{
public delegate void MailSendComplete();
public event MailSendComplete OnMailSendComplete;
private void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
// your code
// finally call the complete event
OnMailSendComplete();
}
public void SentEmail()
{
// your code
}
}
subscribe to this event from calling form as:
Mail m = new Mail();
m.OnMailSendComplete += new Mail.MailSendComplete(m_OnMailSendComplete);
m.SentEmail();
When you receive the complete event you can close the form
void m_OnMailSendComplete()
{
this.Close();
}
Option 2
when you create Mail object you can pass current form reference to it
Mail mail = new Mail(this);
then at the end of SendCompletedCallback you can close the form
public class Mail
{
public Form form { get; set; }
public Mail(Form f)
{
form = f;
}
private void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
// your code
// finally close the form
form.Close();
}
}
i have a simple contact page on my private homepage.
Offline it works perfectly, online nothing happens.
Any idea?
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
btnSend.Attributes.Add("onmouseover", "changeIMG('" + btnSend.ClientID + "', 'Images/Senden_Hover.jpg');");
btnSend.Attributes.Add("onmouseout", "changeIMG('" + btnSend.ClientID + "', 'Images/Senden.jpg')");
}
}
protected void btnSend_Click(object sender, ImageClickEventArgs e)
{
if (!String.IsNullOrEmpty(txtNachricht.Text))
{
SendEmailUserContact(txtAbsender.Text, txtNachricht.Text);
Response.Redirect("~/Contact_suc.aspx", false);
}
}
public static void SendEmailUserContact(string betreff, string nachricht)
{
SendEmail(betreff, nachricht, "von#exampl.com", "an#example.com");
}
private static void SendEmail(string betreff, string nachricht, string von, string an)
{
///Zambuu
string strSmtpServer = "smtp.example.com";
string strUser = "kontakt#example.com";
string strPasswort = "xxx";
MailMessage mail = new MailMessage();
MailAddress from = new MailAddress(von);
mail.To.Add(an);
mail.From = from;
mail.Subject = betreff;
mail.Body = nachricht;
string host = strSmtpServer;
int port = 25;
SmtpClient client = new SmtpClient(host, port);
NetworkCredential nc = new NetworkCredential(strUser, strPasswort);
client.Credentials = nc;
client.Send(mail);
}
I believe the SMTP have approve the sender. So the machine that hosts the online contact page, is a different machine than the one you are developing on. You have to give access on the mailserver on the machine that hosts the page.