Sending Email in ASP.Net #2 - c#

I use the following code to send email.Sometimes it works fine and some time it generate error .
Is there any better code to send emails.And one more thing is it necessary to provide password for sending mail.
using System.Net.Mail;
public void SendEmail()
{
MailMessage mail = new MailMessage();
mail.To.Add("sales#ojhatraders.com");
mail.From = new MailAddress("ojhatraderscustomer#gmail.com");
mail.Subject = "Contact Us Enquiry";
string Body = "<b>From:<b>" + mail.From + "<br/>" + "Your Query Recived "+"<br/>"+"Name"+nameTextBox.Text+"<br/>"+"Mobile:"+mobileTextBox.Text+"<br/>"
+"Email:"+emailTextBox.Text+"<br/>"+"Query:"+queryTextBox.Text;
mail.Body = Body;
mail.IsBodyHtml = true;
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com"; //Or Your SMTP Server Address
smtp.Credentials = new System.Net.NetworkCredential("sample#gmail.com", "passsword");//Or your Smtp Email ID and Password
smtp.EnableSsl = true;
smtp.Send(mail);
}
Please provide some useful suggestion and better code.

Have you tried adding
smtp.Port = 587;
The best bet to keep your credentials secret is having an SMTP Server running that accepts anonymous referrers. With this criteria met, credentials aren't required with anonymous requests. There are fewer and fewer mail services allowing anonymous requests, while it used to be rampant < 10 years ago. Now most SMTP services require valid username and password credentials, some even network domain credentials.

Error
Without informing us with the error that your code generates, we can't really help solving that issue. You should check the recommended smtp-port. From Google support websuite:
If you tried configuring your SMTP server on port 465 (with SSL) and port 587 (with TLS), but are still having trouble sending mail, try configuring your SMTP to use port 25 (with SSL).
'Better' code
Sending mails are quite obvious in ASP.NET so 'better' code to send mails is more an opinion rather than a fact. However, I should split things up a little bit from an architectural point of view. This will improve code quality and reduce duplicate code.
Things you should consider do to make this code 'better'.
Make use of a stringbuilder to build your mail content and inject it into mailtemplate
Make a separate class 'Email' with e.g. default constructor, Send() and GetTemplate() method
Specify settings for SMTP in your web.config
That way you can make and send your e-mail from anywhere in your application in a few lines. Some example code from one of my applications:
var content = new StringBuilder();
content.Append("Name: " + contactForm.Name + "<br/>");
content.Append("Email: " + contactForm.Name + "<br/>");
content.Append("Message: " + contactForm.Name + "<br/>");
//Email constructor accepts two arguments: the content and the name of the template
var mail = new Email(content, "mailTemplateName")
mail.Send("mymail#domain.be", "recipient#gmail.com", "Subject of the mail")

Try including a port for your SMTP. Ones that are typically used are 25, 465, and 587. I usually use 25 without issues and you can also use 465 for ssl. I also usually set UseDefaultCredentials to false:
SmtpClient smtp = new SmtpClient();
smtp.Port = 25;
smtp.UseDefaultCredentials = false;
Also, you might want to dispose of your messages after you've used them. It's good practice and is safer for performance and cost.
using (smtp as IDisposable)
{
smtp.Send(yourEmail);
yourEmail.Dispose();
}
All in all, pretty open ended question. Hope this helps, but be a little more specific so you can get better help next time

Related

SMTP 5.7.57 error when trying to send email via Office 365

I'm trying to set up some code to send email via Office 365's authenticated SMTP service:
var _mailServer = new SmtpClient();
_mailServer.UseDefaultCredentials = false;
_mailServer.Credentials = new NetworkCredential("test.user#mydomain.com", "password");
_mailServer.Host = "smtp.office365.com";
_mailServer.TargetName = "STARTTLS/smtp.office365.com"; // same behaviour if this lien is removed
_mailServer.Port = 587;
_mailServer.EnableSsl = true;
var eml = new MailMessage();
eml.Sender = new MailAddress("test.user#mydomain.com");
eml.From = eml.Sender;
eml.to = new MailAddress("test.recipient#anotherdomain.com");
eml.Subject = "Test message";
eml.Body = "Test message body";
_mailServer.Send(eml);
This doesn't appear to be working, and I'm seeing an exception:
The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM
at System.Net.Mail.MailCommand.Send(SmtpConnection conn, Byte[] command, String from)
at System.Net.Mail.SmtpTransport.SendMail(MailAddress sender, MailAddressCollection recipients, String deliveryNotify, SmtpFailedRecipientException& exception)
at System.Net.Mail.SmtpClient.Send(MailMessage message)
I've tried enabling network tracing and it appears that secure communications are established (for example, I see a line in the log for the "STARTTLS" command, and later there's a line in the log "Remote certificate was verified as valid by the user.", and the following Send() and Receive() data is not readable as plain text, and doesn't appear to contain any TLS/SSH panics)
I can use the very same email address and password to log on to http://portal.office.com/ and use the Outlook email web mail to send and read email, so what might be causing the authentication to fail when sending email programmatically?
Is there any way to additionally debug the encrypted stream?
In my case after I tried all this suggestion without luck, I contacted Microsoft support, and their suggestion was to simply change the password.
This fixed my issue.
Note that the password wasn't expired, because I logged on office365 with success, however the reset solved the issue.
Lesson learned: don't trust the Office 365 password expiration date, in my case the password would be expired after 1-2 months, but it wasn't working.
This leaded me to investigate in my code and only after a lot of time I realized that the problem was in the Office365 password that was "corrupted" or "prematurely expired".
Don't forget every 3 months to "refresh" the password.
To aid in debugging, try temporarily switching to MailKit and using a code snippet such as the following:
using System;
using MailKit.Net.Smtp;
using MailKit.Security;
using MailKit;
using MimeKit;
namespace TestClient {
class Program
{
public static void Main (string[] args)
{
var message = new MimeMessage ();
message.From.Add (new MailboxAddress ("", "test.user#mydomain.com"));
message.To.Add (new MailboxAddress ("", "test.recipient#anotherdomain.com"));
message.Subject = "Test message";
message.Body = new TextPart ("plain") { Text = "This is the message body." };
using (var client = new SmtpClient (new ProtocolLogger ("smtp.log"))) {
client.Connect ("smtp.office365.com", 587, SecureSocketOptions.StartTls);
client.Authenticate ("test.user#mydomain.com", "password");
client.Send (message);
client.Disconnect (true);
}
}
}
}
This will log the entire transaction to a file called "smtp.log" which you can then read through and see where things might be going wrong.
Note that smtp.log will likely contain an AUTH LOGIN command followed by a few commands that are base64 encoded (these are your user/pass), so if you share the log, be sure to scrub those lines.
I would expect this to have the same error as you are seeing with System.Net.Mail, but it will help you see what is going on.
Assuming it fails (and I expect it will), try changing to SecureSocketOptions.None and/or try commenting out the Authenticate().
See how that changes the error you are seeing.
Be sure you're using the actual office365 email address for the account. You can find it by clicking on the profile button in Outlook365. I wrestled with authentication until I realized the email address I was trying to use for authentication wasn't the actual mailbox email account. The actual account email may have the form of: account#company.onmicrosoft.com.
We got ours working by converting the mailboxes (from address) from "shared" to "regular". Before this change, my application quit sending email when we migrated from Gmail to Office 365. No other code changes were required, besides setting the host to smtp.office365.com.
Please check below code I have tested to send email using Exchange Online:
MailMessage msg = new MailMessage();
msg.To.Add(new MailAddress("YourEmail#hotmail.com", "XXXX"));
msg.From = new MailAddress("XXX#msdnofficedev.onmicrosoft.com", "XXX");
msg.Subject = "This is a Test Mail";
msg.Body = "This is a test message using Exchange OnLine";
msg.IsBodyHtml = true;
SmtpClient client = new SmtpClient();
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential("XXX#msdnofficedev.onmicrosoft.com", "YourPassword");
client.Port = 587; // You can use Port 25 if 587 is blocked
client.Host = "smtp.office365.com";
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.EnableSsl = true;
try
{
client.Send(msg);
}
catch (Exception ex)
{
}
Port (587) was defined for message submission. Although port 587 doesn't mandate requiring STARTTLS, the use of port 587 became popular around the same time as the realisation that SSL/TLS encryption of communications between clients and servers was an important security and privacy issue.
In my case my problem was not related to the code but something to do with the Exchange mailbox. Not sure why but this solved my problem:
Go to the exchange settings for that user's mailbox and access Mail Delegation
Under Send As, remove NT AUTHORITY\SELF and then add the user's account.
This gives permissions to the user to send emails on behalf of himself. In theory NT AUTHORITY\SELF should be doing the same thing but for some reason that did not work.
Source: http://edudotnet.blogspot.com.mt/2014/02/smtp-microsoft-office-365-net-smtp.html
I got this same error while testing, using my own domain email account during development. The issue for me seemed related to the MFA (Multi Factor Authentication) that's enabled on my account. Switching to an account without MFA resolved the issue.
I had this issue since someone had enabled Security defaults in Azure.
This disables SMTP/Basic authentication. It's clearly stated in the documentation, but it's not evident by the error message, and you have to have access to the account to find out.
https://learn.microsoft.com/en-us/azure/active-directory/fundamentals/concept-fundamentals-security-defaults
It's possible to enable it per account.
https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/authenticated-client-smtp-submission
You need change the credentials function. Here is the substitution you need to make:
change
-*_mailServer.Credentials = new NetworkCredential("test.user#mydomain.com", "password");*
for this
-*_mailServer.Credentials = new NetworkCredential("test.user#mydomain.com", "password", "domain");*
In my case, password was expired.I just reset password and its started working again

Can't send email using implicit SSL smtp server

I wrote up a sample program by copying the code in this KB article with some little edit as far as user's info. It uses the deprecate .NET library System.Web.Mail to do it because the new System.Net.Mail does not support implicit SSL. I went and tested it with Google smtp server on port 465 which is their implicit email port and everything works. However, when I gave this to a client to test it at his network, nothing get sent/receive, here is the error:
2013-03-07 15:33:43 - The transport failed to connect to the server.
2013-03-07 15:33:43 - at System.Web.Mail.SmtpMail.LateBoundAccessHelper.CallMethod(Object obj, String methodName, Object[] args)
2013-03-07 15:33:43 - at System.Web.Mail.SmtpMail.CdoSysHelper.Send(MailMessage message)
2013-03-07 15:33:43 - at System.Web.Mail.SmtpMail.Send(MailMessage message)
I'm not very well versed when it comes to email SSL so here is my possible theory to the root cause:
Assume he is using the right smtp server and right port (SSL port), I wonder if if any of the following could be the cause:
They are using SSL on the mail server and yet he does not have the certificate installed on the machine where he runs my program from even though he is on the same domain and use the same email domain as a sender.
They are using SSL but they maybe using NTLM or Anonymous authentication while my program uses basic authentication.
Sorry if I provide little information because I myself is quite foreign in this area so I'm still researching more.
Do you know of any steps I can do at my end to ensure my little test program can send using the smtp server of an implicit SSL email server?
Edit: I did add the following line in my code to indicates I'm using SSL.
oMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl", "true");
Maybe this is to late to answer but have a look on https://sourceforge.net/p/netimplicitssl/wiki/Home/
You can send mail to port 465
Without the need of modifying your code, that much.
From the wiki page of project :
var mailMessage = new MimeMailMessage();
mailMessage.Subject = "test mail";
mailMessage.Body = "hi dude!";
mailMessage.Sender = new MimeMailAddress("you#gmail.com", "your name");
mailMessage.IsBodyHtml = true;
mailMessage.To.Add(new MimeMailAddress("yourfriend#gmail.com", "your friendd's name"));
mailMessage.Attachments.Add(new MimeAttachment("your file address"));
var emailer = new SmtpSocketClient();
emailer.Host = "your mail server address";
emailer.Port = 465;
emailer.EnableSsl = true;
emailer.User = "mail sever user name";
emailer.Password = "mail sever password" ;
emailer.AuthenticationMode = AuthenticationType.PlainText;
emailer.MailMessage = mailMessage;
emailer.OnMailSent += new SendCompletedEventHandler(OnMailSent);
//Send email
emailer.SendMessageAsync();
// A simple call back function:
private void OnMailSent(object sender, AsyncCompletedEventArgs asynccompletedeventargs)
{
Console.Out.WriteLine(asynccompletedeventargs.UserState.ToString());
}
Here I am using gmail smtp to send mail using c#. See the code below. It will give you an insight, How the stuffs are working. Replace gmail settings with your email server settings. Dont worry about the security certificates, they will be taken care of by the framework itself.
public static bool SendMail(string to, string subject, string body)
{
bool result;
try
{
var mailMessage = new MailMessage
{
From = new MailAddress("your email address")
};
mailMessage.To.Add(new MailAddress(to));
mailMessage.IsBodyHtml = true;
mailMessage.Subject = subject;
mailMessage.Body = body;
var userName = "your gmail username";
var password = "your gmail password here";
var smtpClient = new SmtpClient
{
Credentials = new NetworkCredential(userName, password),
Host = smtp.gmail.com,
Port = 587,
EnableSsl = true
};
smtpClient.Send(mailMessage);
result = true;
}
catch (Exception)
{
result = false;
}
return result;
}
The piece of code you were referencing was pretty old and obselete too. CDO was used in ASP apps to send mails. I think you havent scroll down to see
Article ID: 555287 - Last Review: April 7, 2005 - Revision: 1.0
APPLIES TO
Microsoft .NET Framework 1.1
You are refering a code that is pretty old... anyways follow the code shown up, everything will be FINE...
UPDATE
My bad, I have'nt read it carefully. But
I am leaving the above code as it is, as it might be a help for you
or any other guy, who need the mailing functionality via SSL over
gmail or any other server later.
. Then in such case you need some third party app.I found you a library See here

How do I send email from C# without revealing my password?

I found a great way to send email in C#, except for one problem, I have to show my password. If anyone were to disassemble my program, or if I decided to make it open source (which I probably will) they would get the username and password for my gmail account. Is there any way to get around this?
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
mail.From = new MailAddress("Contact#pandorafreed.com");
mail.To.Add("myemail#gmail.com");
mail.Subject = "Pandora Free-D Message";
mail.Body = "Name: " + C.NameBox.Text + "\n" + "Email: " + C.emailBox.Text + "\n" + C.Message.Text;
SmtpServer.Port = 587;
SmtpServer.Credentials = new System.Net.NetworkCredential("username", "password");
SmtpServer.EnableSsl = true;
SmtpServer.Send(mail);
+++++EDIT+++++
hmmm... would localhost work? Anyone know?
Not if your mail server requires authentication. The program will need to know the password to send mail, and if this program is operating on a computer you don't trust then you can assume the password will be quickly compromised.
You should consider an alternate method, like submitting the mail via a web service or HTTP call to a server under your control, where you can validate the message and then send it to the mail server.
You could create web-service, which will send e-mail to mail-server.
Why would you have others using your account to send e-mail? Let the user use his/her own mailserver and authentication. Let the user enter those values when installing your program and store it in a configuration file.

Troubleshooting "The server committed a protocol violation" when sending mail with SmtpClient

I want to send a mail message with the SmtpClient class.
Here's the code I use:
SmtpClient smtpClient = new SmtpClient("Host",25);
NetworkCredential basicCredential =
new NetworkCredential("UserName", "Password");
MailMessage message = new MailMessage();
MailAddress fromAddress = new MailAddress("me#domain.com");
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = basicCredential;
message.From = fromAddress;
message.Subject = "test send";
message.IsBodyHtml = true;
message.Body = "<h1>hello</h1>";
message.To.Add("mail#domain.com");
smtpClient.Send(message);
But it always throws an exception:
The server committed a protocol violation The server response was: UGFzc3dvcmQ6
I can't find the reason for that. Please, if anyone has faced something like this, tell me what to do.
I had the same problem, for my case it was for setting user#domain instead of user, I mean
Old code
new NetworkCredential("UserName#domain.com", "Password");
New code
new NetworkCredential("UserName", "Password");
This looks to me like SmtpClient authentication is somehow getting out of step.
Some authentication mechanisms are "Client: request auth with username and password, Server: success/fail" others are "Client: request auth with username, Server: request password, Client: reply with password, Server: success/fail".
It looks like SmtpClient is expecting the former, while your server is expecting the latter.
As dave wenta suggested, a log of a session would tell you what auth mechanism SmtpClient is trying to use, but it will also say what auth mechanisms the server supports.
What normally happens is that the server offers a number of authetication options, and the client choses which one it is going to use. The behaviour from there should be determined by the protocol chosen. I would hope that the SmtpClient class took care of that for you though, but I'm afraid I've never used that particular class.
Also remember - If you are going to post a log here, change to a throwaway password before you log the session, as a base64 encoded plain text password can be trivially changed back to human readable plain text password.
UGFzc3dvcmQ6 is "Password:" base 64 encoded (without quotes), meaning the password is probably wrong or not send encoded. Try base 64 encoding the password:
string password = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("Password));
Enable logging for System.Net.Mail. Then view the log file. This will show you exactly what is happening during the SMTP layer.
Here is a link with more info:
http://systemnetmail.com/faq/4.10.aspx
thousand of hit on google for UGFzc3dvcmQ6
it seem the server expect encrypted(with base64) username/password
Had the same problem. Solved it in the following steps:
1) find out, what the server offers for SMTP Authentication by connecting to the SMTP Server using Telnet or putty or any other terminal:
telnet xxx.yyy.zzz.aaa 587
(xxx.yyy.zzz.aaa = IP address of the SMTP Server, 587 = port number)
< Server answers with "220 protocol + version + time"
ehlo testing
< Server displays list of capabilities e.g.
250-AUTH NTLM CRAM-MD5 LOGIN
The SMTP client tries to take the most secure protocol first. In my case:
1. System.Net.Mail.SmtpNegotiateAuthenticationModule
2. System.Net.Mail.SmtpNtlmAuthenticationModule
3. System.Net.Mail.SmtpDigestAuthenticationModule
4. System.Net.Mail.SmtpLoginAuthenticationModule
It looks as if the SMTP client tries NTLM while the server tries to run LOGIN.
With a hack (cf. https://blogs.msdn.microsoft.com/knom/2008/04/16/hacking-system-net-mail-smtpclient/), all protocols can be turned of except for the one the server assumes (LOGIN in this case):
FieldInfo transport = smtpClient.GetType().GetField("transport", BindingFlags.NonPublic | BindingFlags.Instance);
FieldInfo authModules = transport.GetValue(smtpClient).GetType().GetField("authenticationModules",BindingFlags.NonPublic | BindingFlags.Instance);
Array modulesArray = authModules.GetValue(transport.GetValue(smtpClient)) as Array;
foreach (var module in modulesArray)
{
Console.WriteLine(module.ToString());
}
// System.Net.Mail.SmtpNegotiateAuthenticationModule
// System.Net.Mail.SmtpNtlmAuthenticationModule
// System.Net.Mail.SmtpDigestAuthenticationModule
// System.Net.Mail.SmtpLoginAuthenticationModule
// overwrite the protocols that you don't want
modulesArray.SetValue(modulesArray.GetValue(3), 0);
modulesArray.SetValue(modulesArray.GetValue(3), 1);
modulesArray.SetValue(modulesArray.GetValue(3), 2);
This can also happen when you simply don't provide the password. In my case I was using credentials from a web.config smtp block and on my deployment server (using octopus deploy) had forgotten to populate the password attribute.
For anyone else coming across this on google.. I fixed this by supplying my username in the "username" format instead of "DOMAIN\username"
$Credential = Get-Credential
Send-MailMessage -SmtpServer exchange.contoso.com -Credential $Credential -From 'user#contoso.com' -To 'recipient#domain.com' -Subject 'Test email' -Port 587 -UseSsl

How to Send Email via Yandex SMTP (C# ASP.NET)

Formerly, I used my server as mail host and was sending emails via my own host. Now, I use Yandex as my mail server. I'm trying to send emails via Yandex SMTP. However, I could not achieve it. I get "the operation has timed out" message every time. I'm able to send & receive email with the same settings when I use Thunderbird. Hence, there is no issue with the account. I appreciate your guidance. You can see my code below:
EmailCredentials credentials = new EmailCredentials();
credentials.Domain = "domain.com";
credentials.SMTPUser = "email#domain.com";
credentials.SMTPPassword = "password";
int SmtpPort = 465;
string SmtpServer = "smtp.yandex.com";
System.Net.Mail.MailAddress sender = new System.Net.Mail.MailAddress(senderMail, senderName, System.Text.Encoding.UTF8);
System.Net.Mail.MailAddress recipient = new System.Net.Mail.MailAddress(recipientEmail, recipientName, System.Text.Encoding.UTF8);
System.Net.Mail.MailMessage email = new System.Net.Mail.MailMessage(sender, recipient);
email.BodyEncoding = System.Text.Encoding.UTF8;
email.SubjectEncoding = System.Text.Encoding.UTF8;
System.Net.Mail.AlternateView plainView = System.Net.Mail.AlternateView.CreateAlternateViewFromString(System.Text.RegularExpressions.Regex.Replace(mailBody, #"<(.|\n)*?>", string.Empty), null, MediaTypeNames.Text.Plain);
System.Net.Mail.AlternateView htmlView = System.Net.Mail.AlternateView.CreateAlternateViewFromString(mailBody, null, MediaTypeNames.Text.Html);
email.AlternateViews.Clear();
email.AlternateViews.Add(plainView);
email.AlternateViews.Add(htmlView);
email.Subject = mailTitle;
System.Net.Mail.SmtpClient SMTP = new System.Net.Mail.SmtpClient();
SMTP.Host = SmtpServer;
SMTP.Port = SmtpPort;
SMTP.EnableSsl = true;
SMTP.Credentials = new System.Net.NetworkCredential(credentials.SMTPUser, credentials.SMTPPassword);
SMTP.Send(email);
After so many trials & errors, I have found how to make it work. I have made the following changes on the code posted in the question:
Set SmtpPort = 587
Added the following 2 lines of code:
SMTP.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
SMTP.UseDefaultCredentials = false;
Additional note:
I use Azure server. I realized later that I did not configure the smtp endpoint for port 465. That being said, I had to add the 2 lines of code above in order to make email delivery work, just changing the port was not enough. My point is it is worth to check the defined ports on Azure and firewall before doing anything further.
I was able to make my code work by getting help from #Uwe and also #Dima-Babich, #Rail who posted on the following page Yandex smtp settings with ssl
. Hence, I think credits to answer this question should go to them.
Try using port 25 instead of 465 specified in Yandex help. I found this info on https://habrahabr.ru/post/237899/. They mentioned that it might be due to the fact that explicit SSL mode was implemented in the SmtpClient. Then port 25 is used for establishing connection in unencrypted mode and after that, protected mode is switched on.
I had the same problem.
I solved it by going to the Yandex mail, and then change some settings.
Go to:
1- Settings.
2- Email clients.
3- Set selected POP3 setting that is all.

Categories