I've written a mail method and I'm setting the from email address but when the customer receives it, it's the same as the username that is used to authenticate the email.
I've tried to set the email right before the send and it still comes out wrong:
When I check the message, as shown above, the from is correct but the customer receives it from the username field instead.
public static EmailResults SendEmail(EmailSettings emailSettings)
{
var emailResults = new EmailResults();
try
{
// using mimekit that the msdn smtpclient webpage suggested using
// http://www.mimekit.net/docs/html/Introduction.htm
if (emailSettings.TestModeEnabled)
{
emailResults.IsSuccessful = true;
emailResults.Message = "SendEmail disabled due to TestModeEnabled being set to true.";
return emailResults;
}
// use the mimemessage to create the message to send
var message = new MimeMessage();
message.From.Add(emailSettings.FromEmail);
message.Subject = emailSettings.EmailSubject;
// to email has the option for multiple emails to be sent to
// loop through them and add them all to the message
foreach (var mailboxAddress in emailSettings.ToEmail)
{
message.To.Add(mailboxAddress);
}
// attach file if present
var builder = new BodyBuilder();
if (emailSettings.FileAttachments != null)
{
foreach (var file in emailSettings.FileAttachments)
{
if (File.Exists(file))
{
builder.Attachments.Add(file);
}
}
}
builder.HtmlBody = emailSettings.EmailBody;
message.Body = builder.ToMessageBody();
//// http://www.mimekit.net/docs/html/Creating-Messages.htm
//// A TextPart is a leaf-node MIME part with a text media-type. The first argument to the
//// TextPart constructor specifies the media-subtype, in this case, plain. Another media
//// subtype you are probably familiar with is the html subtype. Some other examples
//// include enriched, rtf, and xml.
//message.Body = new TextPart("html")
//{
// Text = emailSettings.EmailBody
//};
// bcc has the option for multiple emails to be sent to
// loop through them and add them all to the message
if (emailSettings.BccEmail != null)
{
foreach (var mailboxAddress in emailSettings.BccEmail)
{
message.Bcc.Add(mailboxAddress);
}
}
// *************** SEND EMAIL *******************
var client = emailSettings.EnableSmtpLog ? new MailKit.Net.Smtp.SmtpClient(new ProtocolLogger(GlobalVariables.SmptpLogFile)) : new MailKit.Net.Smtp.SmtpClient();
using (client)
{
if (emailSettings.SmtpServer.Contains("gmail.com"))
{
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
}
client.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
//accept all SSL certificates
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
// client.Connect(emailSettings.SmtpServer, emailSettings.SmtpPort, emailSettings.IsSslEnabled);
client.Connect(emailSettings.SmtpServer, emailSettings.SmtpPort, emailSettings.AuthType);
if (emailSettings.IsAuthenticationRequired)
{
// Note: only needed if the SMTP server requires authentication
client.Authenticate(emailSettings.SmtpUsername, emailSettings.SmtpPassword);
}
if (emailSettings.TimeOut == 0) emailSettings.TimeOut = 10;
client.Timeout = emailSettings.TimeOut * 1000;
//message.From.Add(new MailboxAddress("someone#somewhere.net"));
client.Send(message);
client.Disconnect(true);
}
// if we reached this far, then the email was sent successfully
emailResults.Message = "Successfully sent.";
emailResults.IsSuccessful = true;
return emailResults;
}
catch (AuthenticationException e)
{
Logging.LogException("SmtpClient.SendEmail", "Error attempting to send email.", e);
emailResults.IsSuccessful = false;
emailResults.Message = "Invalid username or password.";
return emailResults;
}
catch (Exception e)
{
Logging.LogException("SmtpClient.SendEmail", "Error attempting to send email.", e);
emailResults.IsSuccessful = false;
if (e.Message.Contains("error occurred while attempting to establish an SSL or TLS connection"))
{
emailResults.Message = "An error occurred while attempting to establish a secure connection.\r\n\r\nPlease check your email settings.";
}
else
{
emailResults.Message = e.Message;
}
return emailResults;
}
}
Anyone have any suggestions on what I'm doing wrong?
For anyone who runs in to this again...
This particular issue is specific to Gmail. I'm not sure if other email hosts do the same.
If you are setting the from email address to "person1#email.com" but authenticating with "person2#gmail.com", Gmail will override the from email address with the authentication email address. You have no control over this.
Go to the Gmail account, into settings, and add the alias address in the "Send Mail As" section. The outgoing email should now display with the alias address rather than the authenticating address.
Related
I want to fetch the details from my outlook mailbox but don't have the Microsoft exchange server. I only have cloud-based services.
I tried to use the below-given code but that is an exchange server API solution. The second method is to open the outlook app and then accessing the mailbox but doesn't want this solution.
try
{
'Mailbox credentials'
string emailAddress = AppSettings.Office365EmailAddress;
string password = AppSettings.Office365Password;
ServicePointManager.ServerCertificateValidationCallback =
CertificateValidationCallBack;
ExchangeService service = new
ExchangeService(ExchangeVersion.Exchange2013_SP1);
service.Credentials = new WebCredentials(emailAddress, password);
service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
service.PreAuthenticate = true;
service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress,
emailAddress);
ItemView view = new ItemView(int.MaxValue);
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox,
SetFilter(), view);
DataTable dtEmails = GenerateEmailDataTable();
DataRow dr = dtEmails.NewRow();
foreach (Item item in findResults.Items)
{
if (item.Subject != null)
{
Match match = Regex.Match(item.Subject.ToString(), regJMSNumber);
if (match != null)
{
dr["EmailTo"] = item.DisplayTo.ToString();
dr["EmailFrom"] = item.DisplayTo.ToString();
dr["EmailCC"] = item.DisplayCc.ToString();
dr["EmailBCC"] = item.DisplayTo.ToString();
dr["EmailSubject"] = item.Subject.ToString();
dr["EmailBody"] = item.Body.ToString();
dr["CreatedOn"] = item.Subject.ToString();
dr["IsActive"] = true;
}
else
{
Console.WriteLine("Subject Not Match");
}
}
}
}
'Error handler.'
catch (System.Exception e)
{
Console.WriteLine("{0} Exception caught: ", e);
}
finally
{
}
Another approach is the Power Automate option but I want to do it programmatically.
Used https://outlook.office365.com/EWS/Exchange.asmx API.
When I am using EWS (exchange API), the application throwing a 401 Unauthorised requests failed exception.
Please tell me any other way to track the outlook emails with all details like EmailTo, EmailSent, EmailSubject, EmailBody, EmailCC, EmailBCC, and all the trailing messages.
I am trying to send email using a TCP connection in C# to an smtp server (google in this example).
The response I am getting is that Authentication is required.
5.5.1 Authentication Required. Learn more at\n5.5.1 https://support.google.com/mail/?p=WantAuthError h66sm663716vke.21 - gsmtp
There is no authentication. I don't know the username and password of the account I am sending email TO.
All the other examples I have been able to find use a pre-build SMTP server and build a mail message.
I just want to be able to send email to ANY email account when someone needs to reset their password or I need to send a system message or whatever.
Here is my code:
TcpClient tcpclient = new TcpClient();
tcpclient.Connect("smtp.gmail.com", 465);
//not sure if I need port 465 or 587.
// implicit SSL is always used on SMTP port 465
System.Net.Security.SslStream sslstream = new System.Net.Security.SslStream(tcpclient.GetStream());
sslstream.AuthenticateAsClient("smtp.gmail.com");
writer = new StreamWriter(sslstream);
reader = new StreamReader(sslstream);
string replyText = string.Empty;
string[] capabilities = null;
// read the server's initial greeting
readResponse(220);
// identify myself and get the server's capabilities
if (sendCommand("EHLO myserver.com", ref replyText) == 250)
{
// parse capabilities
capabilities = replyText.Split(new Char[] { '\n' });
}
else
{
// EHLO not supported, have to use HELO instead, but then
// the server's capabilities are unknown...
capabilities = new string[] { };
sendCommand("HELO myserver.com", 250);
}
// check for pipelining support... (OPTIONAL!!!)
if (Array.IndexOf(capabilities, "PIPELINING") != -1)
{
// can pipeline...
// send all commands first without reading responses in between
writer.WriteLine("MAIL FROM:<" + "myserver#myserver.com" + ">");
writer.WriteLine("RCPT TO:<" + "anyemail#gmail.com" + ">");
writer.WriteLine("DATA");
writer.Flush();
// now read the responses...
Exception e = null;
// MAIL FROM
int replyCode = readResponse(ref replyText);
if (replyCode != 250)
e = new SmtpCmdFailedException(replyCode, replyText);
// RCPT TO
replyCode = readResponse(ref replyText);
if ((replyCode != 250) && (replyCode != 251) && (e == null))
e = new SmtpCmdFailedException(replyCode, replyText);
// DATA
replyCode = readResponse(ref replyText);
if (replyCode == 354)
{
// DATA accepted, must send email followed by "."
writer.WriteLine("Subject: Email test");
writer.WriteLine("Test 1 2 3");
writer.WriteLine(".");
writer.Flush();
// read the response
replyCode = readResponse(ref replyText);
if ((replyCode != 250) && (e == null))
e = new SmtpCmdFailedException(replyCode, replyText);
}
else
{
// DATA rejected, do not send email
if (e == null)
e = new SmtpCmdFailedException(replyCode, replyText);
}
if (e != null)
{
// if any command failed, reset the session
sendCommand("RSET");
throw e;
}
}
else
{
// not pipelining, MUST read each response before sending the next command...
sendCommand("MAIL FROM:<" + "myserver#myserver.com" + ">", 250);
try
{
sendCommand("RCPT TO:<" + "anyemail#gmail.com" + ">", 250, 251);
sendCommand("DATA", 354);
writer.WriteLine("Subject: Email test");
writer.WriteLine("");
writer.WriteLine("Test 1 2 3");
writer.Flush();
sendCommand(".", 250);
}
catch (SmtpCmdFailedException e)
{
// if any command failed, reset the session
sendCommand("RSET");
throw;
}
}
// all done
sendCommand("QUIT", 221);
You will need a DNS library that allows you to lookup the MX records of the recipient's domain and then connect to that SMTP server address.
Read more here: https://serverfault.com/questions/392770/smtp-session-between-2-mail-servers-on-the-internet-without-authentication
This question already has answers here:
Sending email through Gmail SMTP server with C#
(31 answers)
Closed 3 years ago.
As the title above, I have created a project with simple log-in and registration. Inside the program, I have use System.Net.Mail.SmtpException to send the email verification to the user email. I have done created the email but when I click on create a new account, I met this problem as well.
System.Net.Mail.SmtpException: 'The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required
From the information I search, I found out someone say I need to make my email 2-step verification. I did it but the problem still there.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Web;
using System.Web.Mvc;
using Food_Founder.Models;
namespace Food_Founder.Controllers
{
public class UserController : Controller
{
//Registration
[HttpGet]
public ActionResult Registration()
{
return View();
}
//Post Registration
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Registration([Bind(Exclude = "IsEmailVerified,ActivationCode")]User user)
{
//Model Validation
bool Status = false;
string message = "";
//Email is already exist
if (ModelState.IsValid)
{
#region Email is already exist
var isExist = IsEmailExist(user.Email);
if (isExist)
{
ModelState.AddModelError("EmailExist", "Email already exist");
return View(user);
}
#endregion
#region Generate Activation Code
user.ActivationCode = Guid.NewGuid();
#endregion
#region Password Hashing
user.Password = Crypto.Hash(user.Password);
user.ConfirmPassword = Crypto.Hash(user.ConfirmPassword);
#endregion
user.IsEmailVerified = false;
#region Save Data to Database
using (myDatabaseEntities myDatabase = new myDatabaseEntities())
{
myDatabase.Users.Add(user);
myDatabase.SaveChanges();
//Send Email to User
SendVerificationLinkEmail(user.Email, user.ActivationCode.ToString());
message = "Registration successfully done. Account activation link" +
"has been send to your Email:" + user.Email + "Please go check and activate your account";
Status = true;
}
#endregion
}
else
{
message = "Invalid Request";
}
ViewBag.Message = message;
ViewBag.Status = Status;
return View(user);
}
//Verify Email
//Verify Email Link
//Login
//Login POST
//Logout
[NonAction]
public Boolean IsEmailExist(string email)
{
using (myDatabaseEntities myDatabase = new myDatabaseEntities())
{
var v = myDatabase.Users.Where(a => a.Email == email).FirstOrDefault();
return v != null;
}
}
[NonAction]
public void SendVerificationLinkEmail(string email, string activationCode)
{
var verifyUrl = "/User/VerifyAccount/" + activationCode;
var link = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, verifyUrl);
var fromEmail = new MailAddress("yukwokyao2#gmail.com", "yukwokyao");
var toEmail = new MailAddress(email);
var fromEmailPassword = "********";
string subject = "Your account is successfully created!";
string body = "<br/><br/>We are excited to tell you that your FoodFounder account is" +
"successfully created. Please click the below link to verify your FoodFounder account" +
"<a href = '" + link + "' >" + link + "</a>";
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromEmail.Address, fromEmailPassword)
};
using (var message = new MailMessage(fromEmail, toEmail)
{
Subject = subject,
Body = body,
IsBodyHtml = true
})
smtp.Send(message);
}
}
}
The code above is the controller class I created. The problem I found is there so that I didn't put any other design html code in here. The most weird part is even I met this problem, the data I register still can key-in into the database but this annoying problem still exist there. Anywhere, if anything I miss put, please inform me ya.. Thank you.
If you are using your Gmail account as SMTP server you need to allow access from what Google calls "less secure apps". You can enable it from your Google settings.
I have a system that sends emails with inline pictures. The problem is how Outlook 2013 displays the attachments. Can I update my code in a way that tells outlook not to display the paperclip icon seen here?
The idea is that I only want to display this icon when full sized pictures are attached. Not inline attachments.
Here's the code that generates the email. Create a basic console app, specify your To / mailserver / picture path, and run.
static void Main(string[] args)
{
Console.WriteLine("Prepping email message....");
var subject = "Test Subject With Inline";
var message = "<p>This is a test message.</p><br/><br/><p>[CompanyLogo]</p>";
var to = new List<string>();
to.Add("My.Name#company.com");
Console.WriteLine("Sending email message....");
if (SendMessageToFrom(subject, message, to, new List<string>()))
{
Console.WriteLine("Email sent! Check your inbox.");
}
else
{
Console.WriteLine("Error sending email!");
}
}
public static bool SendMessageToFrom(String subject, String message, List<String> to, List<String> cc)
{
try
{
// Construct the email
var sendMessage = new MailMessage()
{
IsBodyHtml = true,
From = new MailAddress("noreply#company.com"),
Subject = subject,
Body = message
};
if (sendMessage.Body.Contains("[CompanyLogo]"))
{
sendMessage.AlternateViews.Add(EmbedLogo(sendMessage.Body));
}
// Add the list of recipients
foreach (var recipient in to)
{
sendMessage.To.Add(recipient);
}
foreach (var recipient in cc)
{
sendMessage.CC.Add(recipient);
}
//Specify the SMTP server
var smtpServerName = "mailserver.company.com";
var mailClient = new SmtpClient(smtpServerName);
mailClient.Send(sendMessage);
return true;
}
catch
{
throw;
}
}
private static AlternateView EmbedLogo(string html)
{
var inline = new LinkedResource("img\\company-logo.jpg");
inline.ContentId = Guid.NewGuid().ToString();
html = html.Replace("[CompanyLogo]", string.Format(#"<img src='cid:{0}'/>", inline.ContentId));
var result = AlternateView.CreateAlternateViewFromString(html, null, System.Net.Mime.MediaTypeNames.Text.Html);
result.LinkedResources.Add(inline);
return result;
}
Update: Here's the code that did the trick:
private static MailMessage EmbedLogo(MailMessage mail)
{
var inline = new Attachment("img\\company-logo.jpg");
inline.ContentId = Guid.NewGuid().ToString();
inline.ContentDisposition.Inline = true;
inline.ContentDisposition.DispositionType = DispositionTypeNames.Inline;
mail.Body = mail.Body.Replace("[CompanyLogo]", string.Format(#"<img src='cid:{0}'/>", inline.ContentId));
mail.Attachments.Add(inline);
return mail;
}
And I also updated the main method to this:
if (sendMessage.Body.Contains("[CompanyLogo]"))
{
sendMessage = EmbedLogo(sendMessage);
}
Make sure your attachments have the Content-ID MIME header and the message's HTML body refers to them using the cid attribute : <img src="cid:xyz"> (where xyz is the value of the Content-ID MIME header).
Im trying to find a method in mailkit that executes the command "Execute append" in IMAP, in C# i would do it like:
MailMessage mg = null;
using (ImapClient cl = new ImapClient("imap.gmail.com"))
{
cl.Port = 993;
cl.Ssl = true;
cl.UserName = "xxxxx";
cl.Password = "yyyyy";
var bl = cl.Authenticate();
if (bl == true)
{
//Add Draft
var smg = new SmtpMessage("xxx#gmail.com", "yyy#hotmail.com","yyy#hotmail.com", "This is a test mail.", "Hi.Is it correct??");
cl.ExecuteAppend("GMail/Drafts", smg.GetDataText(), "\\Draft",DateTimeOffset.Now);
}
}
However observing MailKit ImapClient, i dont have this option..
How can i execute append in MailKit IMAP?
After some hours searching....
using (var client = new ImapClient())
{
try
{
client.Connect(ConfigurationManager.AppSettings["ImapServer"], int.Parse(ConfigurationManager.AppSettings["ImapPort"]), SecureSocketOptions.Auto);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
// MailKit uses by default ntlm authentication
client.Authenticate("username", "password");
var draftFolder = client.GetFolder(SpecialFolder.Drafts);
if (draftFolder != null)
{
draftFolder.Open(FolderAccess.ReadWrite);
draftFolder.Append(message, MessageFlags.Draft);
draftFolder.Expunge();
}
else
{
var toplevel = client.GetFolder(client.PersonalNamespaces[0]);
var DraftFolder = toplevel.Create(SpecialFolder.Drafts.ToString(), true);
DraftFolder.Open(FolderAccess.ReadWrite);
DraftFolder.Append(message, MessageFlags.Draft);
DraftFolder.Expunge();
}
}
catch (Exception ex)
{
throw new ApplicationException("IMAPException has occured: " + ex.Message);
}
client.Disconnect(true);
}