ASP.net MVC 5 project SMTP function error [duplicate] - c#

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.

Related

Mailkit is sending emails with the incorrect from address

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.

C# - Connect to Outlook 2010 Mailbox to take Xls Files

I had a a c# script that connects to an OFFICE 365 mailbox and then take any emails with an xls file and puts it in a shared folder. Problem is now the OFFICE 365 mailbox has becomes an Outlook 2010 on premises mailbox, and the script has stopped working.
My questions is what Service URL and service credentials do I use, Is it the same syntax or do I need a new way of connecting in the script ?
OLD script
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Exchange.WebServices.Data;
namespace ST_0710846949654fbd84606ec3011bd081.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
/*
The execution engine calls this method when the task executes.
To access the object model, use the Dts property. Connections, variables, events,
and logging features are available as members of the Dts property as shown in the following examples.
To reference a variable, call Dts.Variables["MyCaseSensitiveVariableName"].Value;
To post a log entry, call Dts.Log("This is my log text", 999, null);
To fire an event, call Dts.Events.FireInformation(99, "test", "hit the help message", "", 0, true);
To use the connections collection use something like the following:
ConnectionManager cm = Dts.Connections.Add("OLEDB");
cm.ConnectionString = "Data Source=localhost;Initial Catalog=AdventureWorks;Provider=SQLNCLI10;Integrated Security=SSPI;Auto Translate=False;";
Before returning from this method, set the value of Dts.TaskResult to indicate success or failure.
To open Help, press F1.
*/
public void Main()
{
ExchangeService service = new ExchangeService();
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
service.Credentials = new WebCredentials("xxreturns#xxxxxxxxxxxx.co.uk", "PasswordXXXXXXXXX", "mail.xxxxxxxxxxxxxxx.co.uk");
service.Url = new Uri("https://mail.xxxxxxxxxxx.co.uk/owa");
// Variable population
string FileName1 = null;
string attSaveLocation = Dts.Variables["User::attSaveLocation"].Value.ToString();
string destfold = Dts.Variables["User::destFolder"].Value.ToString();
string emailFrom = Dts.Variables["User::emailFrom"].Value.ToString();
string filetype = Dts.Variables["User::filetype"].Value.ToString();
//find items in the email folder
FindItemsResults<Item> foundItems =
service.FindItems(WellKnownFolderName.Inbox, new ItemView(600)); //can limit how many results are pulled
foreach (Item item in foundItems)
{
string tmpitemid;
string processed = null;
tmpitemid = item.Id.ToString();
if (item is EmailMessage)
{
// Bind to an existing message item, requesting its Id property (using the tmpitemid) plus its attachments collection.
EmailMessage foundEmail = EmailMessage.Bind(service, new ItemId(tmpitemid), new PropertySet(BasePropertySet.IdOnly, ItemSchema.Attachments));
EmailMessage foundEmail2 = (EmailMessage)item;
FindFoldersResults findResults = service.FindFolders(WellKnownFolderName.Inbox, new FolderView(10));
//get the from e-mail address for exchange addresses
string fromaddress = null;
NameResolutionCollection nd = service.ResolveName(foundEmail2.From.Address);
foreach (NameResolution nm in nd)
{
if (nm.Mailbox.RoutingType == "SMTP")
{
fromaddress = nm.Mailbox.Address.ToLower();
}
else
{
fromaddress = foundEmail2.From.Address.ToString().ToLower();
}
}
//for other addresses
if (fromaddress == null)
{
fromaddress = foundEmail2.From.Address.ToString().ToLower();
}
//if the email address is like the parameter
if (fromaddress.Contains(emailFrom))
{
//process attachments
foreach (Attachment attachment in foundEmail.Attachments)
{
if (attachment is FileAttachment)
{
FileAttachment fileAttachment = attachment as FileAttachment;
FileName1 = attSaveLocation + fileAttachment.Name;
if (fileAttachment.Name.Contains(filetype))
{
fileAttachment.Load(FileName1);
processed = "Y";
}
}
}
if (processed == "Y")
{
// Get all the folders in the message's root folder.
Folder rootfolder = Folder.Bind(service, WellKnownFolderName.Inbox);
rootfolder.Load();
foreach (Folder folder in rootfolder.FindFolders(new FolderView(100)))
{
if (folder.DisplayName == destfold)
{
foundEmail2.Move(folder.Id);
}
}
}
}
}
}
Dts.TaskResult = (int)ScriptResults.Success;
}
}
}
Not sure if this works for Outlook 2010, but perhaps this link can help you:
https://msdn.microsoft.com/en-us/office/office365/api/mail-rest-operations

How to send an email when editing post has been successful ASP.NET MVC 4

i would like to add some more functionalities to my method, such as an email to be sent once the user has successfully edited the data. i could need with some help as i do not how to approach this functionality.
[HttpPost]
public ActionResult Edit(EditPTG eptg)
{
try
{
using (ManageGrade gradLogic = new ManageGrade(ref uow))
{
foreach (var ptg in eptg.ptgForGrade)
{
ptg.Overwritten = true;
ptg.Active = true;
productToGradeLogic.Update(ptg);
}
gradLogic.Update(eptg.grade);
TempData["Success"] = "Edit Successful";
MailMessage mail = new MailMessage();
return RedirectToAction("Index");
}
}
catch
{
TempData["Failure"] = "Edit Failed, Please Review Your Selections and Try Again.";
return View(eptg);
}
}

How to solve the error occurred in password recovery?

I'm using asp.net c# with EF and i'm trying to reset the password when user forget it. And in there i'm sending an email link to the user's provided email if it is in the database.
But it'll give me an error at the point member = Membership.GetUser(foundemail); saying
{"An error occurred while attempting to initialize a System.Data.SqlClient.SqlConnection object. The value that was provided for the connection string may be wrong, or it may contain an invalid syntax.\r\nParameter name: connectionString"}
Here is my code in the controller
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ResetPassword(ResetPasswordModel resetpasswordmodel)
{
if (ModelState.IsValid)
{
//User user;
MembershipUser member;
using (TheFoodyContext db = new TheFoodyContext())
{
/*var foundemail = (from e in db.Users
where e.email == resetpasswordmodel.Email
select e.email).FirstOrDefault();*/
var foundemail = (db.Users.Find(resetpasswordmodel.Email)).email.ToString();
if (foundemail != null)
{
member = Membership.GetUser(foundemail);
}
else
{
member = null;
}
}
if (member != null)
{
//Generate password token that will be used in the email link to authenticate user
var token = WebSecurity.GeneratePasswordResetToken(member.Email);
// Generate the html link sent via email
string resetLink = "<a href='"
+ Url.Action("ResetPasswordView", "Account", new { rt = token }, "http")
+ "'>Reset Password Link</a>";
// Email stuff
string subject = "Reset your password for TheFoody.com";
string body = "You link: " + resetLink;
string from = "abcd123#gmail.com";
string to = resetpasswordmodel.Email;
System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage(from, to);
message.Subject = subject;
message.Body = body;
SmtpClient client = new SmtpClient();
// Attempt to send the email
try
{
client.Send(message);
}
catch (Exception e)
{
ModelState.AddModelError("", "Issue sending email: " + e.Message);
}
}
else // Email not found
{
ModelState.AddModelError("", "No user found by that email.");
}
}
return View(resetpasswordmodel);
}
And here is my connectionString in web.config
<add name="TheFoodyContext" connectionString="metadata=res://*/TheFoodyModel.csdl|res://*/TheFoodyModel.ssdl|res://*/TheFoodyModel.msl;provider=System.Data.SqlClient;provider connection string="data source=DESKTOP-NJOQTOK;initial catalog=TheFoody;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
I'm very new to this environment and can anyone help me?

Call Android Email intent from Unity script

I have a feedback button in unity game, if the user clicks on it then it should launch an default email app with subject, email address filled already. I have done this in Android app but how to call it from unity?
Are there any other better approaches for feedback other than this?
What you are doing is plugin. You don't need plugin for this.
You can simply send email with:
void sendEmail(string toEmail, string emailSubject, string emailBody)
{
emailSubject = System.Uri.EscapeUriString(emailSubject);
emailBody = System.Uri.EscapeUriString(emailSubject);
Application.OpenURL("mailto:" + toEmail + "?subject=" + emailSubject + "&body=" + emailBody);
}
To send, call:
sendEmail("example#example.com", "Test", "This is a text\r\nAnother test\r\nAnd another text");
This will work on PC, Android and iOS. I don't know for Mac.
Now if you still want to use Android API's, you still don't need to make a plugin for this. You can use AndroidJavaObject and write your email code with Android API.
private static void SendMail(string subject, string body, bool useHTML)
{
using (var intentClass = new AndroidJavaClass("android.content.Intent"))
{
// intent = new Intent(Intent.ACTION_SEND);
using (var intentObject = new AndroidJavaObject("android.content.Intent", intentClass.GetStatic<string>("ACTION_SEND")))
{
// Setting text type
if (useHTML)
// intent.setType("text/html");
intentObject.Call<AndroidJavaObject>("setType", "text/html");
else
// intent.setType("message/rfc822");
intentObject.Call<AndroidJavaObject>("setType", "message/rfc822");
// intent.putExtra(Intent.EXTRA_SUBJECT, emailSubject);
intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_SUBJECT"), subject);
// Setting emailBody
if (useHTML)
{
// intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(emailBody));
using (var html = new AndroidJavaClass("android.text.Html"))
{
var htmlBody = html.CallStatic<AndroidJavaObject>("fromHtml", body);
intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_TEXT"), htmlBody);
}
}
else
{
intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_TEXT"), body);
}
using (var unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
using (var currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity"))
{
currentActivity.Call("startActivity", intentObject);
}
}
}
}
}
And to call it SendMail("test", "Message", false);. You can improve it and add more features to it. This last example was lifted from here.
#Programmer's (native-method) answer is correct; but when the user is prompted to select an app to send the email, there's a good chance the user will have the possibility to select apps other than e-mail apps; e.g. WhatsApp. We don't want this to happen. As stated in the docs the way we could ensure that only e-mail apps will be shown to the user, is to use Intent.ACTION_SENDTO and intent.setData(Uri.parse("mailto:").
private void SendMail(string subject, string body)
{
using (var intentClass = new AndroidJavaClass("android.content.Intent"))
{
// intent = new Intent(Intent.ACTION_SEND);
using (var intentObject = new AndroidJavaObject("android.content.Intent", intentClass.GetStatic<string>("ACTION_SENDTO")))
{
//intent.setData(Uri.parse("mailto:"));
var uriClass = new AndroidJavaClass("android.net.Uri");
var uriObject = uriClass.CallStatic<AndroidJavaObject>("parse", "mailto:");
intentObject.Call<AndroidJavaObject>("setData", uriObject);
// intent.putExtra(Intent.EXTRA_SUBJECT, emailSubject);
intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_SUBJECT"), subject);
//intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_EMAIL"), "youremail#abc.xyz");
string[] email = { "youremail#abc.xyz" };
intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_EMAIL"), email);
// Setting emailBody
intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_TEXT"), body);
using (var unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
using (var currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity"))
{
currentActivity.Call("startActivity", intentObject);
}
}
}
}
}
Replace youremail#abc.xyz with the e-mail you intend to send the e-mail to.
The question is, why do all this hassle instead of simply sending the e-mail like stated below:
void sendEmail(string toEmail, string emailSubject, string emailBody)
{
emailSubject = System.Uri.EscapeUriString(emailSubject);
emailBody = System.Uri.EscapeUriString(emailSubject);
Application.OpenURL("mailto:" + toEmail + "?subject=" + emailSubject +
"&body=" + emailBody);
}
You might want to add HTML or some non-Latin text (e.g. Japanese, Arabic) to your e-mail's body. using System.Uri.EscapeUriString is going to mess that up. In that case, the native method will be your method of choice.
On Button click you have to call:
public void OpenActivity()
{
var androidJC = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
var jo = androidJC.GetStatic<AndroidJavaObject>("currentActivity");
// Accessing the class to call a static method on it
var jc = new AndroidJavaClass("com.xyz.abc.StartActivity");
// Calling a Call method to which the current activity is passed
jc.CallStatic("Call", jo);
}
}
Replace it by your activity and package name
var jc = new AndroidJavaClass("com.xyz.abc.StartActivity");

Categories

Resources