I made a random Gmail account.I want that account to send to my personal Gmail account something, using C#. I found out about FluentEmail these days. This is the class:
public static class EmailSender
{
//the random account mail and password
private static string username = "blabla";
private static string password = "blabla";
static EmailSender()
{
NetworkCredential myCredentials = new NetworkCredential();
myCredentials.UserName = username;
myCredentials.Password = password;
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
DeliveryMethod = SmtpDeliveryMethod.Network,
Credentials = myCredentials,
Port = 465,
EnableSsl = true,
};
var sender = new SmtpSender(() => smtp);
Email.DefaultSender = sender;
}
public static async Task SendEmail(string body)
{
var email = await Email
.From(username)
.To("mymail")
.Subject("NEW BUG")
.Body(body)
.SendAsync();
if (email.Successful)
{
Acr.UserDialogs.UserDialogs.Instance.Alert("Your message was sent!", "Succesful", "Ok");
}
}
}
I don't know why but nothing happens when I click the send button.When I click it 2 times in a row the app crashes. I put a breakpoint at the start of the SendEmail function but I still don't know what's wrong. Maybe I set something wrong in the constructor?Thanks.
I'm not familiar with FluentEmail, but there are two points which are obviously problematic:
You check whether the mail has been sent successfully (if (email.Successful)). If it didn't, you just... do nothing. Instead, find out why the mail has not been sent and display that information instead. If your return object has a property Successful, I'm pretty sure it also has a property telling you what went wrong.
I did glimpse at the FluentEmail source code (based on your question), and it apparently uses .NET's built-in SmtpClient class. SmtpClient does not support SMTPS at port 465. The supported options are unauthenticated SMTP at port 25 or STARTTLS at port 587.
Related
The original post was removed and I thought I would revise my latest issue. I understand completely that it has something to do with my username and password but am not sure of what else I can do. I have rest passwords multiple times, deleted and reestablished the username/email address multiple times and even dumped the .Net SmtpClient for the MailKit approach which I am now getting this error.
I am wonder if it has anything to do with me going through Bluehost for my domain and office365 subscription. With that said, as I began developing this application, I have noticed through Telnet I am still unable to establish a connection. Does anybody have any advice on how to send an email with SMTP (or anyway) through office365/outlook?
Here is my code:
Controller:
[HttpPost]
public async Task<IActionResult> SendContactEmail(ContactCardModel contact)
{
string emailSubject = $"Inquiry from {contact.name} from {contact.organization}";
await _emailSender.SendEmailAsync(contact.name, contact.email, emailSubject, contact.message);
ViewBag.ConfirmMsg = "Sent Successful";
return View("Contact");
}
Email Service:
public class SendEmailService : ISendEmail
{
private string _host;
private string _from;
private string _pwd;
public SendEmailService(IConfiguration configuration)
{
//TODO: Collect SMTP Configuration Settings
var smtpSection = configuration.GetSection("SMTP");
_host = smtpSection.GetSection("Host").Value;
_from = smtpSection.GetSection("From").Value;
_pwd = smtpSection.GetSection("Pwd").Value;
}
public async Task SendEmailAsync(string fromName, string fromEmail, string subject, string message)
{
//TODO: Build MailMessage Object
MimeMessage mailMessage = new MimeMessage();
mailMessage.From.Add(new MailboxAddress(fromName, fromEmail));
mailMessage.To.Add(new MailboxAddress("App Admin", "tyler.crane#odin-development.com"));
mailMessage.Subject = subject;
BodyBuilder bodyBuilder = new BodyBuilder
{
HtmlBody = message
};
//TODO: Build SmtpClient Object and NetworkCredential Object
SmtpClient smtp = new SmtpClient();
smtp.ServerCertificateValidationCallback = (sender, certificate, certChainType, errors) => true;
smtp.AuthenticationMechanisms.Remove("XOAUTH2");
await smtp.ConnectAsync(_host, 587, SecureSocketOptions.StartTls).ConfigureAwait(false);
await smtp.AuthenticateAsync(new NetworkCredential(_from, _pwd)).ConfigureAwait(false);
await smtp.SendAsync(mailMessage).ConfigureAwait(false);
}
}
Interface:
public interface ISendEmail
{
Task SendEmailAsync(
string fromName,
string fromEmail,
string subject,
string message
);
}
Greatly appreciate anybody willing to help!
I finally figured out my own issue and it wasn't even in the slightest bit that difficult. More importantly, the message itself was very misleading and I am here to shed some light for those who are encountering the same issue.
SmtpClient smtp = new SmtpClient();
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
// The above Certificate Validation Callback has to be exactly as I show it.
// I, for some reason, had invalid options applied and can assure anyone who
// has followed any tutorial whatsoever, what they have inputted is wrong or for dummy
// testing purposes. Once you have this established, host has to be exactly as
// follows: smpt.office365.com and port 587 ONLY(25 is not longer supported).
smtp.AuthenticationMechanisms.Remove("XOAUTH2");
await smtp.ConnectAsync(_host, 587, SecureSocketOptions.StartTls).ConfigureAwait(false);
await smtp.AuthenticateAsync(new NetworkCredential(_from, _pwd)).ConfigureAwait(false);
await smtp.SendAsync(mailMessage).ConfigureAwait(false);
In no way shape or form did my error apply to the actual account itself. Although this may not directly apply to my issue where the tenant username/pass were not the issue, it may still be an issue for anyone. However, I do highly suggest you consider exactly what my code reflects above with the host and port suggestions I have made.
Thank you all who attempted to try and solve this and if anyone has any additional questions, I would be more than happy to answer them. Thanks!
I have attempted to send an email using the GMail SMTP, and followed the guides on various other questions but I still cannot get emails to send from my GMail account.
This is the code I'm using:
protected void emailSend_Click(object sender, EventArgs e)
{
var fromAddress = new MailAddress(inputEmail.Text, inputName.Text);
var toAddress = new MailAddress("spikey666#live.co.uk", "Liane Stevenson");
const string fromPassword = "*********";
const string subject = "Web Dev Wolf Message";
var body = inputMessage.Text;
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
Credentials = new NetworkCredential("webdevelopwolf#gmail.com", fromPassword),
Timeout = 20000
};
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body
})
{
smtp.Send(message);
}
}
These are the things I've checked so far:
Turning on less secure apps on GMail
Checked the Gmail Username and Password are correct
Debugged and checked that all text fields have values and are loaded into variables
Check other port numbers suggested by Gmail help
Turned on POP/IMAP functionality on Gmail
Is there anything else I could be missing?
Before calling SmtpClient.Send(), add:
smtp.UseDefaultCredentials = false;
According to the MSDN SmtpClient page, UseDefaultCredentials is set to false by default, but there seems to be a bug somewhere that is setting it to true. Explicitly set it to false before sending the message and it should be all set.
Okay; I can't seem to send a mail message. I'm running this as a console application:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
namespace Email
{
class Program
{
static void EMail(string ToAddress, string Subject, string Body, string FromAddress, string Host, int Port, string Username, string Password)
{
System.Net.Mail.SmtpClient SMTPClient = new System.Net.Mail.SmtpClient(Host, Port);
System.Net.Mail.MailMessage Message = new System.Net.Mail.MailMessage();
Message.To.Add(new System.Net.Mail.MailAddress(ToAddress));
Message.From = new System.Net.Mail.MailAddress(FromAddress);
Message.Body = Body;
Message.Subject = Subject;
SMTPClient.EnableSsl = true;
SMTPClient.Credentials = new System.Net.NetworkCredential(Username, Password);
SMTPClient.Send(Message);
SMTPClient.SendCompleted += new System.Net.Mail.SendCompletedEventHandler(FinishedSending);
}
static void FinishedSending(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
Console.WriteLine("DONE!");
}
static void Main(string[] args)
{
EMail("***********", "Hi!", "This is a test, Sent from a C# application.", "******", "smtp.gmail.com", 465, "****************", "**************");
Console.ReadLine();
}
}
}
I'm not getting any errors, I'm not recieving it in my gmail account, And it's not writing "DONE!".
I have allowed port 465, outcoming and incoming. Telnetting smtp.gmail.com on port 465 results in a blank command prompt window.
Thanks.
Email should be going through if there is no exception.
It is not printing "DONE!" because you are hooking into the event after calling Send() method. Hook in the even before calling send.
Edit: And yes it should be SendAsync. Send is synchronous.
Also try these parameters in this order:
smtpClient.EnableSsl = true;
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = (...)
This code works for me, in a new Winforms application:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
static void smtpClient_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
var state = e.UserState;
//"Done"
}
private void Form1_Load(object sender, EventArgs e)
{
var smtpClient = new SmtpClient("smtp.gmail.com", 587)
{
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential("myEmail#gmail.com", "mypassword")
};
var message = new MailMessage("myEmail#gmail.com", "myEmail#gmail.com", "Subject", "body");
smtpClient.SendCompleted += new SendCompletedEventHandler(smtpClient_SendCompleted);
smtpClient.SendAsync(message, new object());
}
}
Go to Task -> Actions - > Edit Action and set "Start in (optional)" to folder where the executable file is.
I think that System.Net.Mail.SmtpClient::Send() may not be as synchronous as it should be. I was using this class in a powershell script that was to be run by the Task Scheduler. When running the script from a powershell console, I always received the message. However, when running the script as a scheduled task, I would not.
I resolved the problem by having the script sleep for 1 second after sending--I suspect the SMTP session was being killed by powershell shutting down at the end of the script, which doesn't happen when running it from an interactive session.
I know it's sloppy, but I haven't figured out a better way to make sure it's actually finished. Maybe there's a buffer that has to be flushed?
An alternative might be to call Send() with a bogus message after you send the actual message. I found that the message was consistently sent if I did this. This is still sloppy, but I find it a little bit less sloppy because it is more likely to actually require the buffers to be flushed before sending while waiting an arbitrary amount of time will definitely not cause it.
The reason it doesn't work is because you're targeting port 465. Using EnableSsl with port 25 (although not with Gmail) or port 587 should work for you.
SMTPS on port 465, or "Implicit SSL" as Microsoft calls it in a lot of places, is not supported by the SmtpClient class. The EnableSsl property controls whether or not the class will look for and use the STARTTLS command after an unencrypted connection has been established.
As per the Microsoft SmtpClient.EnableSsl Property documentation:
The SmtpClient class only supports the SMTP Service Extension for
Secure SMTP over Transport Layer Security as defined in RFC 3207. In
this mode, the SMTP session begins on an unencrypted channel, then a
STARTTLS command is issued by the client to the server to switch to
secure communication using SSL. See RFC 3207 published by the Internet
Engineering Task Force (IETF) for more information.
An alternate connection method is where an SSL session is established
up front before any protocol commands are sent. This connection method
is sometimes called SMTP/SSL, SMTP over SSL, or SMTPS and by default
uses port 465. This alternate connection method using SSL is not
currently supported.
If you really need to use SMTPS over port 465 there are solutions using the deprecated System.Web.Mail classes that use CDONTS behind the scenes, e.g. https://stackoverflow.com/a/1014876.
i use the following code to send email :
public static bool SendEmail(string To, string ToName, string From, string FromName, string Subject, string Body, bool IsBodyHTML)
{
try
{
MailAddress FromAddr = new MailAddress(From, FromName, System.Text.Encoding.UTF8);
MailAddress ToAddr = new MailAddress(To, ToName, System.Text.Encoding.UTF8);
var smtp = new SmtpClient
{
Host = "smtp.datagts.net",
Port = 587,
EnableSsl = false,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = true,
Credentials = new System.Net.NetworkCredential("MeEmail#...", "Password")
};
using (MailMessage message = new MailMessage(FromAddr, ToAddr)
{
Subject = Subject,
Body = Body,
IsBodyHtml = IsBodyHTML,
BodyEncoding = System.Text.Encoding.UTF8,
})
{
smtp.Send(message);
}
return true;
}
catch
{
return false;
}
}
It works on local and when i use my web site under my local IIS but when i upload it to my website it does not work and does not send email even any error occurs.
is there anybody out there to help me about this ?
UPDATE1 : i remove the try catch and catch an error with this message : Failure sending mail
UPDATE2 : I change my stmp server and use my Gmail account , look at this code :
public static bool SendEmail(string To, string ToName, string From, string FromName, string Subject, string Body, bool IsBodyHTML)
{
try
{
MailAddress FromAddr = new MailAddress(From, FromName, System.Text.Encoding.UTF8);
MailAddress ToAddr = new MailAddress(To, ToName, System.Text.Encoding.UTF8);
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new System.Net.NetworkCredential("MeEmail#gmail.com", "Password")
};
using (MailMessage message = new MailMessage(FromAddr, ToAddr)
{
Subject = Subject,
Body = Body,
IsBodyHtml = IsBodyHTML,
BodyEncoding = System.Text.Encoding.UTF8,
})
{
smtp.Send(message);
}
return true;
}
catch
{
return false;
}
}
and now i get an error yet :(
I get the "MustIssueStartTlsFirst" error that mentioned in this link.
I am now trying to check #EdFS point and use port 25
UPDATE3: It is because i use the shared server , i just can change the port to 25 , and steel it does not work an give the same error, I am trying to get support from my server backup team
Assuming the SMTP server (smtp.datagts.net) is running fine, some items to check:
Your code seems to be using UseDefaultCredentials=true, but on the next line your are providing credentials
As mentioned in the comments check that Port 587 isn't blocked at your web host
If you are hosted on a shared server (not a dedicated machine), it's likely ASP.Net is set for medium trust. IF so, you cannot use any port for SMTP other than Port 25.
Update:
To try and get to the error. In your LOCAL (development) machine, add this to your web.config:
<system.web>
...
<securityPolicy>
<trustLevel name="Medium" />
</securityPolicy>
...
ASP.Net on your local machine runs in FULL TRUST. The above setting makes the current web site/application you are working on run in medium trust. You can remove/comment as necessary. The point of this exercise is to try and match what your web host settings are (it's obviously different if things work in your local machine then dies when published). It would be nice to just obtain the info from your web host..but until then....
Then try both Port 587 and 25.
It should fail on port 587 with a security exception (because of medium trust)
If your mail server only accepts SMTP connections on port 587, then of course, port 25 will not work either (but you should get a different error). The point being "...it still doesn't work..." in this case is that the SMTP server (smtp.datagts.net) only accepts connections on port 587
GMAIL is the same story. You cannot use Port 587 if your web host settings for ASP.Net is medium trust. I have been through this many times - it will "work" in my local machine, but as soon as I enable medium trust in my local development machine, it will fail.
You should ask your web host what their settings are for ASP.Net - if its some "custom" setting you can ask for a copy and use that in your dev box as well.
I am writing a small utility to help process some MySQL tasks every night and have it email my personal email if it fails (this is a personal project, so no company smtp server or anything, emails going through public outlook accounts).
I tested about 5 times and each send was successful, but now any attempts to send email I get this exception:
Error sending test email: Transaction failed. The server response was: 5.2.0 STOREDRV.Submission.Exception:OutboundSpamException; Failed to process message due to a permanent exception with message WASCL UserAction verdict is not None. Actual verdict is Suspend, ShowTierUpgrade. OutboundSpamException: WASCL UserAction verdict is not None. Actual verdict is Suspend, ShowTierUpgrade.[Hostname=BY2PR0101MB1461.prod.exchangelabs.com]
A bit of an oops on my part - didn't think Outlook would consider it as spam on the 6th try - is there anything I can do in Outlook to correct this?
I am using a service account I created in outlook to send these emails to my personal inbox.
The actual code in question:
class JobMailer
{
private string email_to;
private string email_from;
private string password;
private string email_smtp;
private bool use_ssl;
private int port;
public void Send(string subject, string body)
{
MailMessage mail = new MailMessage(email_from, email_to);
using (SmtpClient client = new SmtpClient
{
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
EnableSsl = use_ssl,
Host = email_smtp,
Timeout = 100000,
Port = port,
Credentials = new NetworkCredential(email_from, password)
})
{
mail.Subject = subject;
mail.Body = body;
client.Send(mail);
}
}
public JobMailer(string emailTo, string smtp, string emailFrom, string pw, int p, bool ssl)
{
email_to = emailTo;
email_from = emailFrom;
password = pw;
email_smtp = smtp;
port = p;
use_ssl = ssl;
}
}
I resolved this by verifying the account I was trying to use. Each time you encounter this error an email is sent to the account with instructions on what you need to do to resolve the error. Typically you will need to verify against a phone number.
Got this error trying to send lots of emails to myself at Outlook.com, using SMTP.
To fix it I simply added a 5 second delay between the sends, for example:
foreach(var mail in mailToSend)
{
await smtpClient.SendMailAsync(mail);
Console.WriteLine("Sent email: " + mail);
await Task.Delay(5000);
}
If you aren't doing this just as a test, then you can contact the Outlook.com team and ask them to whitelist your IP (make sure you have SPF, rDNS, etc. setup first).