how to send an email with an attachment from C#? - c#

I'm trying to write a code, what would save the content of a picturebox ( works ) and email it ( doesn't work ).
What do you think might be the problem? Should there be anything more to the SmtpClient client = new SmtpClient("smtp.gmail.com"); ?
Also the program shouldn't freeze up while the image gets uploaded, rather then, if necessary, be able to simultaneously upload a few images.
System.Drawing.Image img = pictureBox1.Image;
string name = "" + DateTime.Now.ToString("dd_MM_yyyy_HH_mm_ss") + ".jpg";
img.Save(name, System.Drawing.Imaging.ImageFormat.Jpeg);
if (chb_notif.Checked == true) ////////////// SEND EMAIL!
{
MailMessage message = new MailMessage(
"do-not-reply#123.com",
tb_email.Text ,
"VIDEO FENCE",
"Your perimeter has been breeched! System name: " + Environment.MachineName + "." );
Attachment data = new Attachment(name);
ContentDisposition disposition = data.ContentDisposition;
disposition.CreationDate = System.IO.File.GetCreationTime(name);
disposition.ModificationDate = System.IO.File.GetLastWriteTime(name);
disposition.ReadDate = System.IO.File.GetLastAccessTime(name);
message.Attachments.Add(data);
//Send the message.
SmtpClient client = new SmtpClient("smtp.gmail.com");
client.Credentials = CredentialCache.DefaultNetworkCredentials;
client.Send(message);
}
Thanks!

for:
"The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required"
Try use:
var client = new SmtpClient("smtp.gmail.com", 587)
{
Credentials = new NetworkCredential("username", "password"),
EnableSsl =true
};
client.Send(message);

If you dont want your app to hang while this may take some time (if the image is big, or the servers are unresponsive, you need to put it into a separate thread. (Many examples already exist)
As a few of us have also pointed out, you need to also send the Email, your code above doesnt do that. Be aware of course that if gmail thinks you're trying to relay through them, the mail probably wont send.

Related

How to send email from a C# program

I would like to add email functionality to a WinForm program I'm writing in C#. I have an Android app that has email functionality. What it does is set up the email but then lets the user choose the email program, etc. Once that is chosen the email body is completed. But it's up to the use to select what email app they want to use.
I would like to do the same in Windows but I don't see how. I have tried the following (based on other questions and responses here) :
_from = new MailAddress("my email address", "xxxx");
_to = new MailAddress("xxxx3333#gmail.com", "yyyy");
SmtpClient smtp = new SmtpClient("smtp.gmail.com");
smtp.UseDefaultCredentials = true;
smtp.Port = 587;
smtp.EnableSsl = true;
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp msgMail = new MailMessage();
smtp.Body = text;
msgMail.Subject = "Subject";
msgMail.From = _from;
msgMail.To.Add(_to);
smtp.EnableSsl = true;
msgMail.Subject = _subject;
msgMail.Body = Text;
msgMail.IsBodyHtml = false;
try
{
mailClient.Send(msgMail);
}
catch (Exception ex)
{
string msg = "Exception caught in sending the email: " + ex.ToString();
showMessage(msg);
}
msgMail.Dispose();
But I get:
The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required.
With similar code in Android, my program just gets to an email form but lets the user decide what email add they will use.
Is there a way to do this in Windows?
There is an almost identical question and response here:
C# Windows Form Application - Send email using gmail smtp
And I think I've followed this but...doesn't work.
To directly answer your question - you probably haven't enabled less secure apps on the gmail account you are using.
Otherwise though, you could investigate the syntax of mailto if you want to let the user elect a mail client to use to send the email: https://www.labnol.org/internet/email/learn-mailto-syntax/6748/
From the link:
Send an email to Barack Obama with the subject “Congrats Obama” and some text in the body of the email message
<a href=”mailto:obama#whitehouse.gov?
subject=Congrats%20Obama&body=Enjoy%20your%20stay%0ARegards%20″>
This isn't directly related to C#/Windows - but I do know entering mailto:someone#somewhere.com at the Run prompt works:
Presumably then you could do something like: (untested)
Process.Run("mailto:someone#somewhere.com");
From the server response messages it looks like you have to provide login credentials before you are allowed to send.
Replace:
smtp.UseDefaultCredentials = true;
With:
smtp.Credentials = new System.Net.NetworkCredential("yourusername", "yourpassword");
This should do the trick.
You may have forgotten in your code to add the Host
Try to use this :
SmtpClient smtp = new SmtpClient();
smtp.UseDefaultCredentials = true;
smtp.Host = "SRVMAIL";

I Can't Send Mail When I Publish My Web Site - ASP.NET Web Forms

I published the site I completed using ASP.NET Web Forms but I'm having trouble sending mail. My web site does not send mail. There is no problem when I run in local.
My Fonksiyon.cs:
public static bool MailGonder(string gonderenaciklama, string kimemail, string kimeadi, string mailkonu, string mailicerik, string kimdenmail = "", bool IletisimFormuMu = false)
{
MailAddress From = new MailAddress(IletisimFormuMu ? kimdenmail : "My e-mail address is here", gonderenaciklama); // Gönderen kısmında görünen e-posta adresi.
MailAddress To = new MailAddress(kimemail, kimeadi); // Mailin gönderileceği adres.
MailMessage EMail = new MailMessage(From, To);
EMail.Subject = mailkonu;
EMail.Body = mailicerik;
EMail.IsBodyHtml = true;
EMail.BodyEncoding = Encoding.Unicode;
SmtpClient MailClient = new SmtpClient();
MailClient.Port = 587;
MailClient.Host = "smtp.gmail.com";
MailClient.EnableSsl = true; // Gmail üzerinden gönderme yapılacaksa veya sunucu kimlik doğrulaması gerektiriyorsa buraya true değerini vereceğiz.
MailClient.UseDefaultCredentials = true;
MailClient.Credentials = new System.Net.NetworkCredential("My e-mail address is here", "My password is here"); // Maili göndereceğimiz hesap bilgileri buraya giriyoruz. Mailimiz bu hesap üzerinden gönderilecek.
MailClient.DeliveryMethod = SmtpDeliveryMethod.Network;
try
{
MailClient.Send(EMail);
return true;
}
catch
{
return false;
}
}
My register.aspx button click:
string guid = Guid.NewGuid().ToString();
Fonksiyon.MailGonder("Ay Tasarım E-Posta Doğrulaması", TxtEPosta.Text, TxtAd.Text + " " + TxtSoyad.Text, "E-Posta Doğrulaması", "Lütfen aşağıdaki aktivasyon kodunu sitemizdeki ilgili alana yazarak üyeliğinizi aktif ediniz!<br />Aktivasyon Kodu: " + guid + "");
Nothing to do with your code, this is security feature of your gmail account.
these are the reasons that you can check
Google's security system has blocked the IP of your server
Google security system is actually pretty cool, if somebody gets his hands on your Gmail's password, well he won't be able to do much, unless he is using your IP address. Why? Because when Google spots an unusual IP address trying to connect to your account it will deny it access and will send you an email and eventually a text message on your mobile phone.
When you send a test email from MailPoet's Settings and you get the following message : " SMTP Error: Could not authenticate. | SMTP Error: Could not connect to SMTP host." then you might be entering this case scenario
The email you will receive to notify you of that unusual access will be as follow :
Allow new IP's in Google account
In your case when you setup your site to send with your Gmail account, you want to allow a new IP to use your Gmail's credentials. In order to allow a new unrecognized app simply go to https://security.google.com/settings/security/activity, find the line that concerns you and allow access.
Hope this helps to resolve your problem....

Closing Transmission Error. Timeout waiting for the data from client

I am using local host to send bulk mails through SES. This question is answered by many but none of the solutions is helping me. The problem is I could send 100/ 150 mails at a time after that the above error is showing up. I tried to dispose of the client as suggested by some, but not working. I am using C# code to do this. Any answers/ suggestions is much appreciated. The below is the code I am using to send bulk mail using for loop. You might be thinking it might be a throttling issue, it is not because we have 70 emails/second and 500000 emails per day.
Parallel.For(0, mail.Count, i =>
{
// Replace with your "From" address. This address must be verified.
String TO = mail; // Replace with a "To" address. If your account is still in the
// sandbox, this address must be verified.
// Create an SMTP client with the specified host name and port.
using (System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(HOST, PORT))
{
// Create a network credential with your SMTP user name and password.
client.Credentials = new System.Net.NetworkCredential(SMTP_USERNAME, SMTP_PASSWORD);
//Use SSL when accessing Amazon SES. The SMTP session will begin on an unencrypted connection, and then
//the client will issue a STARTTLS command to upgrade to an encrypted connection using SSL.
client.EnableSsl = true;
System.Net.Mail.MailMessage message1 = new System.Net.Mail.MailMessage(FROM, TO, SUBJECT, BODY);
message1.IsBodyHtml = true;
client.Send(message1);
client.Dispose();
}
});
I don't know the exact reason why it is working now, but it's working. I changed the logic of the above code, it started working. Instead of fetching the SMTP connection each time, for sending each mail previously, this time I fetched the smtp connection only once and used it to send all the bulk mails at once and it started working.But the problem is the sending time, it is taking too much to send all the mails.Anyways I will find the solution for this also.
using (System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(HOST, PORT))
{
client.Credentials = new System.Net.NetworkCredential(SMTP_USERNAME, SMTP_PASSWORD);
client.EnableSsl = true;
for(i=0;i<mail.Count;i++)
{
String TO = mail[i];
System.Net.Mail.MailMessage message1 = new System.Net.Mail.MailMessage(FROM, TO, SUBJECT, BODY);
message1.IsBodyHtml = true;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Send(message1);
}
client.Dispose();
}
Label1.Text = mail.Count.ToString() + " mails sent !!";

System.Net.Mail Server Response was 5.7.1

I am building a windows forms application for a school that has a very tight network (meaning the person I am building it for has to ask their IT services to do everything).
This application sends emails out and I am using System.Net.Mail library to do so.
SMTPServer = new SmtpClient("SMTPAddress");
MailMessage mailObj = new MailMessage("admin#xyz.com", emailAddressTo);
mailObj.IsBodyHtml = true;
mailObj.Subject = "Subject";
mailObj.Body = "<h2>Test E-Mail Message from the TSENS</h2>";
SMTPServer.Credentials = new System.Net.NetworkCredential(SMTPUserName, SMTPPassword);
SMTPServer.DeliveryMethod = SmtpDeliveryMethod.Network; //This is new code
SMTPServer.Send(mailObj);
I'm wondering if this line: SMTPServer.DeliveryMethod = SmtpDeliveryMethod.Network; will solve the latest error message he got when trying to send out an e-mail:
Is there something else that I am missing?
Just in case you are wondering the SMTPUserName and Password is his e-mail username and password that he uses to send and receive mail.
I presume that the SMTPUsername his mailadress isn't "admin#xyz.com" which is used as the sender of the mailmessage.
The mailserver seems to validate if the person doing the send is allowed to send mails on behalf of admin#xyz.com which appearantly isn't the case.
According to the SMTP specs error 5.7.1 stands for "Unable to relay" which is what you try to do.
emailClient = new SmtpClient(yourEMAILSERVER);
emailClient.Send(yourMailMessageObject); // in your case "mailObj" that you have defined already
I would avoid using SMTPServer class or set its Credentials or DeliveryMethod properties.

How to set username and password for SmtpClient object in .NET?

I see different versions of the constructor, one uses info from web.config, one specifies the host, and one the host and port. But how do I set the username and password to something different from the web.config? We have the issue where our internal smtp is blocked by some high security clients and we want to use their smtp server, is there a way to do this from the code instead of web.config?
In this case how would I use the web.config credentials if none is available from the database, for example?
public static void CreateTestMessage1(string server, int port)
{
string to = "jane#contoso.com";
string from = "ben#contoso.com";
string subject = "Using the new SMTP client.";
string body = #"Using this new feature, you can send an e-mail message from an application very easily.";
MailMessage message = new MailMessage(from, to, subject, body);
SmtpClient client = new SmtpClient(server, port);
// Credentials are necessary if the server requires the client
// to authenticate before it will send e-mail on the client's behalf.
client.Credentials = CredentialCache.DefaultNetworkCredentials;
try {
client.Send(message);
}
catch (Exception ex) {
Console.WriteLine("Exception caught in CreateTestMessage1(): {0}",
ex.ToString());
}
}
The SmtpClient can be used by code:
SmtpClient mailer = new SmtpClient();
mailer.Host = "mail.youroutgoingsmtpserver.com";
mailer.Credentials = new System.Net.NetworkCredential("yourusername", "yourpassword");
Use NetworkCredential
Yep, just add these two lines to your code.
var credentials = new System.Net.NetworkCredential("username", "password");
client.Credentials = credentials;
SmtpClient MyMail = new SmtpClient();
MailMessage MyMsg = new MailMessage();
MyMail.Host = "mail.eraygan.com";
MyMsg.Priority = MailPriority.High;
MyMsg.To.Add(new MailAddress(Mail));
MyMsg.Subject = Subject;
MyMsg.SubjectEncoding = Encoding.UTF8;
MyMsg.IsBodyHtml = true;
MyMsg.From = new MailAddress("username", "displayname");
MyMsg.BodyEncoding = Encoding.UTF8;
MyMsg.Body = Body;
MyMail.UseDefaultCredentials = false;
NetworkCredential MyCredentials = new NetworkCredential("username", "password");
MyMail.Credentials = MyCredentials;
MyMail.Send(MyMsg);
There are a couple of things not mentioned in other answers.
First, it can be necessary to use CredentialCache instead of NetworkCredential directly, in order to specify different authentication schemes.
In the documentation, the SMTP authentication type names are listed as:
"NTLM", "Digest", "Kerberos", and "Negotiate"
However I had to breakpoint within the .NET code to see that the value being passed for "AUTH LOGIN" was actually "login". This seems to happen automatically anyway, so this is only necessary to use different schemes.
Second, though no one here is, you probably do NOT want to specify a domain name in your NetworkCredential. Doing so results in SmtpClient passing a username of the form example.com\username which is almost guaranteed to not be accepted by a mail server. (And if your mail server is loose with its authentication requirements, you may not know that you are failing to authenticate.)
var nc = new NetworkCredential(
username,
password
// no domain!
);
// only if you need to specify a particular authentication scheme,
// though it doesn't hurt to do this anyway if you use the right scheme name
var cache = new CredentialCache();
cache.Add(smtpServerName, port, "NTLM", nc);
// can add more credentials for different combinations of server, port, and scheme
smtpClient.Credentials = cache;
Lastly, note that you do not need to set UseDefaultCredentials if you are also setting Credentials as they are both based on the same underlying value. Setting both can lead to issues since they will just overwrite each other.
If in doubt, use WireShark and disable SSL temporarily (to see the network frames or else they are encrypted), and confirm that your SMTP authentication is working. (Use an "smtp" filter in WireShark).
Since not all of my clients use authenticated SMTP accounts, I resorted to using the SMTP account only if app key values are supplied in web.config file.
Here is the VB code:
sSMTPUser = ConfigurationManager.AppSettings("SMTPUser")
sSMTPPassword = ConfigurationManager.AppSettings("SMTPPassword")
If sSMTPUser.Trim.Length > 0 AndAlso sSMTPPassword.Trim.Length > 0 Then
NetClient.Credentials = New System.Net.NetworkCredential(sSMTPUser, sSMTPPassword)
sUsingCredentialMesg = "(Using Authenticated Account) " 'used for logging purposes
End If
NetClient.Send(Message)

Categories

Resources