I'm new to web programming and I am making a website using ASP.NET Core. I am trying to create a standard "contact me" page where the user enters in a name, email, subject and message. ASP.NET Core has yet to have System.Net.Mail, so I can't use that.
I saw that MailKit could be used to send emails, but am unable to figure out how to use it for a contact page. I know using this code
using (var client = new SmtpClient ()) {
client.Connect ("smtp.friends.com", 587, false);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove ("XOAUTH2");
// Note: only needed if the SMTP server requires authentication
client.Authenticate ("joey", "password");
client.Send (message);
client.Disconnect (true);
I can send an email using my SMTP server, but obviously I want the functionality of users using the site to be able to send an email to me. Is there a way to use MailKit for this, or do I need to find another solution? Thanks.
Edit:
This is the code I have that successfully sends an email, but it always says that it was sent from me to me.
public IActionResult SendEmail(Contact contact)
{
var emailMessage = new MimeMessage();
emailMessage.From.Add(new MailboxAddress(contact.Name, contact.Email));
emailMessage.To.Add(new MailboxAddress("myname", "myemail"));
emailMessage.Subject = contact.Subject;
emailMessage.Body = new TextPart("plain") { Text = contact.Message };
using (var client = new SmtpClient())
{
client.Connect("smtp-mail.outlook.com", 587);
client.Authenticate("myemail", "myemailpassword");
client.Send(emailMessage);
client.Disconnect(true);
}
return RedirectToAction("Index", "Home");
}
Yes, MailKit can be used for this purpose.
The problem you are seeing is because outlook.com is replacing your From header with your email address (it's a "feature" of outlook.com when you login via SMTP).
You might be able to sort of work around this by setting the ReplyTo to the user's address (so you can reply to them).
Or you could try setting the From to the user's address and setting the Sender to your address (not sure if this will work).
Related
Context
I'm developing an application using WPF and .NET 5 for a research institute. The client would like to receive an email when something goes wrong during an experience because it can last several days.
Before adding this feature to the software, I made a simple test program to send an email from a console application and it worked... mostly.
Disclaimer : I know there are tons of threads about this subject, and I have read nearly a hundred. The code itself doesn't seem to be the problem and I did setup the google account with two factor authentication (I also tried the "Less secure app" option).
The problem
I said the problem doesn't seem to be the code because I actually managed to send emails that way, using my personal gmail address. Problem is, I don't want to use my own address to send mail to the client... So I created an new gmail address and enabled 2FA. And when I try to send an email with the new address I get this in the emitter inbox :
What I already tried
I've tried various recipient and port with the same result. I've looked for this issue on google support, on forums and on youtube but I didn't find anything similar to my problem. I even waited 2 weeks to make sure it wasn't because the address was too recent and judged as "untrustworthy" or something like that.
The code I used
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
MailAddress to = new MailAddress("recipient#gmail.com");
MailAddress from = new MailAddress("emitter#gmail.com");
MailMessage message = new MailMessage(from, to);
message.Subject = "Using the new SMTP client.";
message.Body = "Using this new feature, you can send an e-mail message from an application very easily.";
message.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
SmtpClient client = new SmtpClient
{
EnableSsl = true,
Port = 587,
Host = "smtp.gmail.com",
Timeout = 10000,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential("emitter#gmail.com", "app-specific-password")
};
try
{
client.Send(message);
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in Main(): {0}",
ex.ToString());
}
message.Dispose();
}
What I would like
I just need to be able to send a few emails per day, to one or two contacts, from a WPF application. Nothing fancy. It seems that the two options I got are :
to find how to create a neutral email address that can use gmail smtp
or
to find another (easy and free) solution to send emails.
Can you help me with that, please ?
I am using Azure Sendgrid to send emails from my ASP.net core web application. Intermittently, emails are not being received by some of the recipients. Some recipients receive the email, others do not.
Code below is for brevity, not including setting up MailMessage (FROM, TO, etc...)
I am using "smtp.sendgrid.net" as smtpserver with "port" 587 as smtpport.
string smtpServer = ConfigurationManager.AppSettings["MailSMTPServer"];
int smtpPort = int.Parse(ConfigurationManager.AppSettings["MailPort"]);
string username = ConfigurationManager.AppSettings["MailUserName"];
string pwd = ConfigurationManager.AppSettings["MailPassword"];
SmtpClient client = new SmtpClient(smtpServer);
client.Port = smtpPort;
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential(username, pwd);
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Send(mailMessage);
I have talked with the IT dept where emails are not being received to see if they are being blocked. There is no record of the emails hitting their server.
It's recommended to use their REST API over SMTP.
SMTP relay creates multiple points of potential failure, meaning that there are more places in the conversation between the sender and
SendGrid that could cause one of those “not okay” messages.
The Web API is faster. The extra back and forth necessary in SMTP relay can cause some (minimal) latency for customers who are outside
of the United States, and thus further from our inbound data centers.
The Web API also allows you to add an extra layer of security to your program by utilizing API keys. API keys allow you to generate an
authentication credential separate from your username password, which
significantly lowers the chance of someone using your account to send
spam or phish.
Also, there might be whitelisting issue due to outbound SMTP restriction in Azure. If you use REST API instead, you can overcome that.
Here is a C# example using their nuget.
var apiKey = "<send grid api key>";
var client = new SendGridClient(apiKey);
var from = new EmailAddress("test#example.com", "Example User");
var subject = "Sending with SendGrid is Fun";
var to = new EmailAddress("test#example.com", "Example User");
var plainTextContent = "and easy to do anywhere, even with C#";
var htmlContent = "<strong>and easy to do anywhere, even with C#</strong>";
var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
var response = await client.SendEmailAsync(msg);
I create a method for send Email like:
public async Task SendEmailCC(string body, string subject, List<string> mainRecievers, List<string> receivers)
{
SmtpClient client = new SmtpClient("smtp-mail.outlook.com")
{
UseDefaultCredentials = true,
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
Credentials = new NetworkCredential("Test#gmail.com", "MyMailPassword")
};
MailMessage mailMessage = new MailMessage { From = new MailAddress("job#test.org") };
foreach (var reciever in mainRecievers)
{
mailMessage.To.Add(reciever);
}
foreach (var item in receivers)
{
mailMessage.CC.Add(item);
}
mailMessage.Body = body;
mailMessage.IsBodyHtml = true;
mailMessage.Subject = subject;
await client.SendMailAsync(mailMessage);
}
For test, I send an email to my self, but I didn't get Email. how can I find my problem?
My exception is connection auth.
Mail server was google and I used of OutLookSmtp,To this section of my code I have that and I changed. like:
SmtpClient client = new SmtpClient("smtp-mail.outlook.com")
And changed:
SmtpClient client = new SmtpClient("smtp.gmail.com")
After that I get this exception:
The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required", than the error might occur due to following cases.
For this issue I try this:
case 1: when the password is wrong
case 2: when you try to login from some App
case 3: when you try to login from the domain other than your time zone/domain/computer (This is the case in most of scenarios when sending mail from code)
There is a solution for each
solution for case 1: Enter the correct password.
solution 1 for case 2: go to security settings at the followig link https://www.google.com/settings/security/lesssecureapps and enable less secure apps . So that you will be able to login from all apps.
solution 2 for case 2:(see https://stackoverflow.com/a/9572958/52277) enable two-factor authentication (aka two-step verification) , and then generate an application-specific password. Use that newly generated password to authenticate via SMTP.
solution 1 for case 3: (This might be helpful) you need to review the activity. but reviewing the activity will not be helpful due to latest security standards the link will not be useful. So try the below case.
solution 2 for case 3: If you have hosted your code somewhere on production server and if you have access to the production server, than take remote desktop connection to the production server and try to login once from the browser of the production server. This will add excpetioon for login to google and you will be allowed to login from code.
But what if you don't have access to the production server. try the solution 3
solution 3 for case 3: You have to enable login from other timezone / ip for your google account.
to do this follow the link https://g.co/allowaccess and allow access by clicking the continue button.
And that's it. Here you go. Now you will be able to login from any of the computer and by any means of app to your google account
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
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