Email sending in aspnet identity - c#

I wrote following method to send emails
public ActionResult SendEmail(UserData user)
{
try
{
#region Email content
MailMessage m = new MailMessage(
new MailAddress("sender#email.com", "Represent Location"),
new MailAddress(Reciever_Email));
m.Subject = "Mail Topic";
m.IsBodyHtml = true;
m.Body = string.Format("<img src=\"##IMAGE##\" alt=\"\"><BR/><BR/>Hi " + user.FirstName + "," + "<BR/><BR/>Your account has been successfully created with the Comp. Please click on the link below to access your account.<BR/><BR/>" + "Username - " + user.UserName + "<BR/>" + "Password - " + user.Password + "<BR/><BR/>" + "Please click here to Activate your account", user.UserName, Url.Action("ConfirmEmail", "Account", new { Token = user.Id, Email = user.UserEmail }, Request.Url.Scheme)) + string.Format("<BR/><BR/>Regards,<BR/>The Human Resource Department <BR/>");
// create the INLINE attachment
string attachmentPath = System.Web.HttpContext.Current.Server.MapPath("~/Images/logo.jpg");
// generate the contentID string using the datetime
string contentID = Path.GetFileName(attachmentPath).Replace(".", "") + "#zofm";
Attachment inline = new Attachment(attachmentPath);
inline.ContentDisposition.Inline = true;
inline.ContentDisposition.DispositionType = DispositionTypeNames.Inline;
inline.ContentId = contentID;
inline.ContentType.MediaType = "image/png";
inline.ContentType.Name = Path.GetFileName(attachmentPath);
m.Attachments.Add(inline);
// replace the tag with the correct content ID
m.Body = m.Body.Replace("##IMAGE##", "cid:" + contentID);
SmtpClient smtp = new SmtpClient("Email_Server_IP");
smtp.Port = ServerPort;
smtp.Credentials = new NetworkCredential("sender#email.com", "sender_password");
smtp.EnableSsl = false;
smtp.Send(m);
#endregion
return View(user);
}
catch (Exception ex)
{
throw ex;
}
}
then I'm accessing above method in main controller like following
// Email Sending
UserData sampleData = new UserData();
sampleData.Id = user.Id;
sampleData.UserName = user.UserName;
sampleData.UserEmail = user.Email;
sampleData.FirstName = user.FirstName;
sampleData.Password = model.Password;
// await EmailController.Sendemail(sampleData);
var emailCntrl = new EmailController();
var sendEmail = emailCntrl.SendEmail(sampleData);
this is compiling without any compile times errors. but when I debug this I can see
in this line m.Body = str... I can see a error like this
because of that I'm getting an exception
Message = "Object reference not set to an instance of an object."
How can I solve this

You don't have Request, because you create just EmailController class. When controller factory creates controller for request it passes request data to Controller.Initialize Method.
Of course the best practice is to create EmailService as was mentioned above, but as answer for your question, you can make workaround. You can pass RequestContext of parent controller to EmailController in constructor and call Initialize. It's going to look like.
public EmailController()
{
}
public EmailController(RequestContext requestContext)
{
base.Initialize(requestContext);
}
And in your controller
var emailCntrl = new EmailController(this.ControllerContext.RequestContext);
var sendEmail = emailCntrl.SendEmail(sampleData);

You can also just set the ControllerContext
var emailCntrl = new EmailController(){ControllerContext = this.ControllerContext};
var sendEmail = emailCntrl.SendEmail(sampleData);

Well given that there was no request added to controller before calling action, it would be null.
There is no need for a controller there just to send the email.
Create a class/service to handle the email and pass in any dependencies
public class EmailService {
public UserData SendEmail(UserData user, string confirmationEmailUrl) {
try
{
#region Email content
MailMessage m = new MailMessage(
new MailAddress("sender#email.com", "Represent Location"),
new MailAddress(Reciever_Email));
m.Subject = "Mail Topic";
m.IsBodyHtml = true;
m.Body = string.Format("<img src=\"##IMAGE##\" alt=\"\"><BR/><BR/>Hi " + user.FirstName + "," + "<BR/><BR/>Your account has been successfully created. Please click on the link below to access your account.<BR/><BR/>" + "Username - " + user.UserName + "<BR/>" + "Password - " + user.Password + "<BR/><BR/>" + "Please click here to Activate your account", user.UserName, confirmationEmailUrl + string.Format("<BR/><BR/>Regards,<BR/>The Human Resource Department <BR/>");
// create the INLINE attachment
string attachmentPath = System.Web.HttpContext.Current.Server.MapPath("~/Images/logo.jpg");
// generate the contentID string using the datetime
string contentID = Path.GetFileName(attachmentPath).Replace(".", "") + "#zofm";
Attachment inline = new Attachment(attachmentPath);
inline.ContentDisposition.Inline = true;
inline.ContentDisposition.DispositionType = DispositionTypeNames.Inline;
inline.ContentId = contentID;
inline.ContentType.MediaType = "image/png";
inline.ContentType.Name = Path.GetFileName(attachmentPath);
m.Attachments.Add(inline);
// replace the tag with the correct content ID
m.Body = m.Body.Replace("##IMAGE##", "cid:" + contentID);
SmtpClient smtp = new SmtpClient("Email_Server_IP");
smtp.Port = ServerPort;
smtp.Credentials = new NetworkCredential("sender#email.com", "sender_password");
smtp.EnableSsl = false;
smtp.Send(m);
#endregion
return user;
}
catch (Exception ex)
{
throw ex;
}
}
}
And get the action from main controller
// Email Sending
UserData sampleData = new UserData();
sampleData.Id = user.Id;
sampleData.UserName = user.UserName;
sampleData.UserEmail = user.Email;
sampleData.FirstName = user.FirstName;
sampleData.Password = model.Password;
var confirmationEmailUrl = Url.Link("Default", new { Action = "ConfirmEmail", Controller = "Account", Token = sampleData.Id, Email = sampleData.UserEmail });
var emailService = new EmailService();
var user = emailService.SendEmail(sampleData, confirmationEmailUrl);

Related

How to add image (logo) to email sender MVC

I want to be able to send an email with an image in the body. The below code works but I can't figure out how to add image to it. Thanks for any help!
namespace Identity.Areas.Birthdays.Controllers
{
public class EmailController : ApplicationBaseController
{
private EmployeeInfoEntities db = new EmployeeInfoEntities();
public ActionResult SendEmail(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
EmployeeInfo employeeInfo = db.EmployeeInfoes.Find(id);
if (employeeInfo == null)
{
return HttpNotFound();
}
return View(employeeInfo);
}
[HttpPost]
public ActionResult SendEmail(string receiver, string subject, string message, string from)
{
try
{
if (ModelState.IsValid)
{
var senderEmail = new MailAddress("test#gmail.com");
var receiverEmail = new MailAddress(receiver, "Receiver");
var password = "*********";
var sub = subject;
var body = "<font color='red'>" + "<font size='20px'>" + message + "<br />" + "<br />" + "<font color='blue'>" + from + "</font>" + "</font>" + "</font>";
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(senderEmail.Address, password)
};
using (var mess = new MailMessage(senderEmail, receiverEmail)
{
Subject = subject,
Body = body
})
{
mess.IsBodyHtml = true;
smtp.Send(mess);
ViewBag.Message = "Message Has Been Sent!";
}
return View();
}
}
catch (Exception)
{
ViewBag.Error = "An Error Has Occurred!";
}
return View();
}
}
}
You have to put image in your body string.
var body = "<img src='~/images/sample.jpg' /> <font color='red'>" + "<font size='20px'>" + message + "<br />" + "<br />" + "<font color='blue'>" + from + "</font>" + "</font>" + "</font>";
Make sure the images folder and sample.jpg exists.
Apologies, I realize the above won't work and you will get the broken image in the output because the string won't know that it has to render the image as well.
New solution, even better for cleaner body creation:
use this method.
https://lastloop.blogspot.com/2019/07/send-email-from-c.html
You will add the image tag as we add normally in the html but since you are sending it in the email, the image you want to add, has to be hosted somewhere. For example, like this google logo:
<img srce='https://www.google.com.pk/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png'/>

Forgot password email is not delivered to user

I am new to ASP.NET and C# and this is my first big project.
Unable to send forgot password mail through ASP.NET and C#. Even, neither errors nor exceptions are displayed by Visual Studio.
These are my files:
Code Behind
//Reset password event
protected void btnResetPassword_Click(object sender, EventArgs e)
{
string CS = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
using (SqlConnection con = new SqlConnection(CS))
{
con.Open();
SqlCommand cmd = new SqlCommand("spResetPassword", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter paramUsername = new SqlParameter("#UserName", txtUserName.Text);
cmd.Parameters.Add(paramUsername);
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
if (Convert.ToBoolean(rdr["ReturnCode"]))
{
SendPasswordResetEmail(rdr["EmailID"].ToString(), txtUserName.Text, rdr["UniqueId"].ToString());
lblMessage.Text = "An email with instructions to reset your password is sent to your registered email";
}
else
{
lblMessage.ForeColor = System.Drawing.Color.Red;
lblMessage.Text = "Username not found!";
}
}
}
}
Send Email to Recipient, an email template is been added inline code instead of a using AlternateView.
private void SendPasswordResetEmail(string ToEmail, string UserName, string UniqueId)
{
try
{
MailMessage mailMessage = new MailMessage("Email#gmail.com", ToEmail);
StringBuilder sbEmailBody = new StringBuilder();
sbEmailBody.Append("Dear " + UserName + ",<br/><br/>");
sbEmailBody.Append("Please click on the following link to reset your password");
sbEmailBody.Append("<br/>"); sbEmailBody.Append("http://localhost:64736/SmartE/Registration/ChangePassword.aspx?uid=" + UniqueId);
sbEmailBody.Append("<br/><br/>");
sbEmailBody.Append("<b>Smart Elector</b>");
mailMessage.IsBodyHtml = true;
mailMessage.Body = sbEmailBody.ToString();
mailMessage.Subject = "Reset Your Password";
SmtpClient smtpClient = new SmtpClient("smtp.gmail.com", 587);
smtpClient.Credentials = new System.Net.NetworkCredential()
{
UserName = "Email#gmail.com",
Password = "Password"
};
smtpClient.EnableSsl = true;
smtpClient.Send(mailMessage);
}
catch(Exception ex)
{
lblMessage.Text= "Record Insert Exception: " + ex.Message;
}
}
Stored procedure:
There is no output parameter defined in this stored procedure, which returns the unique code to the invoker. instead, select query is used to return the same.
CREATE PROCEDURE Spresetpassword
#UserName NVARCHAR(100)
AS
BEGIN
DECLARE #UserID INT,
#EmailID NVARCHAR(100);
SELECT
#UserID = userid,
#EmailID = emailid
FROM
globalusers
WHERE
username = #UserName;
IF (#UserID IS NOT NULL)
BEGIN
-- If username exists
DECLARE #GUID UNIQUEIDENTIFIER;
SET #GUID = NEWID();
INSERT INTO tblresetpasswordrequests (id, userid, resetrequestdatetime)
VALUES (#GUID, #UserID, GETDATE())
SELECT
1 AS ReturnCode,
#GUID AS UniqueId,
#EmailID AS EmailID
END
ELSE
BEGIN
-- If username does not exist
SELECT
0 AS ReturnCode,
NULL AS UniqueId,
NULL AS EmailID
END
END
Try this solution using membership,
protected void btnResetPassword_Click(object sender, EventArgs e)
{
MembershipUser mu = Membership.GetUser(txtResetUserName.Text.Trim());
if (mu != null)
{
if (!mu.IsLockedOut)
{
string resetPassword = Membership.GeneratePassword(8, 1);
mu.ChangePassword(mu.ResetPassword(), resetPassword);
ListDictionary replaceList = new ListDictionary();
replaceList.Add("<%UserName%>", "Name of the user");
replaceList.Add("<%NewCode%>", resetPassword);
Utility fetch = new Utility();
fetch.SendMail(mu.Email, string.Empty, "User account " + txtResetUserName.Text.Trim() + " password reset to: " + resetPassword, fetch.MailBodyTemplate(replaceList, "ResetEmailTemplate"), null);
}
}
}
Put the below code in an Utility class of your project.
public void SendMail(string to, string cc, string subject, AlternateView body, string path)
{
MailMessage message = new MailMessage(AppSettings.Default.From, to);
if (!String.IsNullOrEmpty(path)) message.Attachments.Add(new Attachment(path));
if (!String.IsNullOrEmpty(cc)) message.CC.Add(cc);
if (body != null)
{
message.AlternateViews.Add(body);
message.IsBodyHtml = true;
}
message.Body = subject;
message.Subject = subject;
Thread bgThread = new Thread(new ParameterizedThreadStart(SendEmailInBackgroud));
bgThread.IsBackground = true;
bgThread.Start(message);
}
Template based Email body
public AlternateView MailBodyTemplate(ListDictionary replaceList, string fileName)
{
AlternateView plainView = null;
string templatePath = System.Web.Hosting.HostingEnvironment.MapPath("~/Content/MailTemplate/" + fileName + ".txt");
if (File.Exists(templatePath))
{
string templateContent = File.ReadAllText(templatePath);
foreach (DictionaryEntry item in replaceList)
{
if (item.Value != null)
templateContent = templateContent.Replace(item.Key.ToString(), item.Value.ToString());
else
templateContent = templateContent.Replace(item.Key.ToString(), string.Empty);
}
plainView = AlternateView.CreateAlternateViewFromString(templateContent, null, MediaTypeNames.Text.Html);
}
return plainView;
}
Your Email Template File As Follows,
File Name: ResetEmailTemplate.txt
<!DOCTYPE html>
<html><head>
<style>
.ContentBody {
color: #1331a0;
}
</style></head>
<body class="ContentBody">
<p>Dear <%UserName%>,</p>
<p>New Password for your accout is: <%NewCode%> </p>
</body>
</html>

Lotus Notes Sending email with options

I'm using Lotus Domino.dll. Already finished sending. How set delivery options to DeliveryPriority=H and DeliveryReport=C?
CODE
NotesSession _notesSession = new NotesSession();
NotesDocument _notesDocument = null;
string sMailFile = "mail/" + login + ".nsf";
_notesSession.Initialize(passwrod);
NotesDatabase _notesDataBase = _notesSession.GetDatabase(sServerName, sMailFile, false);
if (!_notesDataBase.IsOpen)
{
_notesDataBase.Open();
}
_notesDocument = _notesDataBase.CreateDocument();
_notesDocument.ReplaceItemValue("Form", "Memo");
_notesDocument.ReplaceItemValue("SendTo", aSendTo);
_notesDocument.ReplaceItemValue("Subject", aSubject);
NotesRichTextItem _richTextItem = _notesDocument.CreateRichTextItem("Body");
_richTextItem.AppendText(text + "\r\n");
_richTextItem.EmbedObject(EMBED_TYPE.EMBED_ATTACHMENT, "", file);
var oItemValue = _notesDocument.GetItemValue("SendTo");
_notesDocument.SaveMessageOnSend = true;
_notesDocument.Send(false, ref oItemValue);
Add the lines
_notesDocument.ReplaceItemValue("DeliveryPriority", "H");
_notesDocument.ReplaceItemValue("DeliveryReport", "C");
after your Subject line.
You can find a complete list of mail options here.

New line in code is not working

I'm using this code to send mails to my coworkers. The part at the mailMessage.Body, when I'm using "\r\n" is not working. Instead of showing the e-mail like this:
entity.PrimaryMeal.Title
entity.ScondaryMeal.Title
Porosine mund ta beni ketu: <> (this is in my language AL)
it is showing like this:
entity.PrimaryMeal.Title, entity.ScondaryMeal.Title. Porosine mund ta beni ketu: <>
What am I doing wrong?
private void SendMail(string MailReciever)
{
Configuration configuration = WebConfigurationManager.OpenWebConfiguration(HttpContext.Current.Request.ApplicationPath);
MailSettingsSectionGroup mailSettingsSectionGroup = (MailSettingsSectionGroup)configuration.GetSectionGroup("system.net/mailSettings");
string MailSender = mailSettingsSectionGroup.Smtp.From;
string Username = mailSettingsSectionGroup.Smtp.Network.UserName;
string UserPassword = mailSettingsSectionGroup.Smtp.Network.Password;
string SmtpServer = mailSettingsSectionGroup.Smtp.Network.Host;
int Port = mailSettingsSectionGroup.Smtp.Network.Port;
bool UseSsl = mailSettingsSectionGroup.Smtp.Network.EnableSsl;
bool UseDefaultCredentials = mailSettingsSectionGroup.Smtp.Network.DefaultCredentials;
using (SmtpClient smtpClient = new SmtpClient())
using (MailMessage mailMessage = new MailMessage())
{
mailMessage.To.Add(MailReciever);
mailMessage.From = new MailAddress(MailSender);
mailMessage.Subject = ConfigurationManager.AppSettings["NewMailSubject"];
smtpClient.Host = SmtpServer;
smtpClient.UseDefaultCredentials = UseDefaultCredentials;
smtpClient.Port = Port;
smtpClient.Credentials = new NetworkCredential(Username, UserPassword);
smtpClient.EnableSsl = UseSsl;
#region MailMessageBody
var entity = Factory.Orders.List(item => item.OrderDate == DateTime.Today).ToList().FirstOrDefault();
if (entity.SecondaryMealId == -1)
{
mailMessage.Body = entity.PrimaryMeal.Title + ".\r\nPorosine mund ta beni ketu: http://10.200.30.11:8888";
}
else if (entity.TertiaryMealId == -1)
{
mailMessage.Body = entity.PrimaryMeal.Title + ",\r\n" + entity.SecondaryMeal.Title + ".\r\nPorosine mund ta beni ketu: http://10.200.30.11:8888";
}
else
{
mailMessage.Body = entity.PrimaryMeal.Title + ",\r\n" + entity.SecondaryMeal.Title + ",\r\n" + entity.TertiaryMeal.Title + ".\r\nPorosine mund ta beni ketu: http://10.200.30.11:8888";
}
#endregion
mailMessage.IsBodyHtml = true;
smtpClient.Send(mailMessage);
}
}
mailMessage.IsBodyHtml = true;
You are sending your email as Html (which ignores raw line breaks), you should add the <br> tag instead (or work with paragraphs).
if (entity.SecondaryMealId == -1)
{
mailMessage.Body = entity.PrimaryMeal.Title + ".<br>Porosine mund ta beni ketu: http://10.200.30.11:8888";
}
else if (entity.TertiaryMealId == -1)
{
mailMessage.Body = entity.PrimaryMeal.Title + ",<br>" + entity.SecondaryMeal.Title + ".\r\nPorosine mund ta beni ketu: http://10.200.30.11:8888";
}
else
{
mailMessage.Body = entity.PrimaryMeal.Title + ",<br>" + entity.SecondaryMeal.Title + ",<br>" + entity.TertiaryMeal.Title + ".<br>Porosine mund ta beni ketu: http://10.200.30.11:8888";
}
I think its better to send HTML mail. That means you need to put <br/> instead of \r\n and set Message body type as HTML.

Clear Textboxs on submit

Hi i am looking to clear text boxs when a user clicks a button. However the code that i have is not working. Here is my code.
System.Net.Mail.MailMessage m = new System.Net.Mail.MailMessage();
m.Body = name.Text + Environment.NewLine + phone.Text + Environment.NewLine + email.Text + Environment.NewLine + message.Text;
m.IsBodyHtml = false;
m.To.Add("support#");
m.From = new System.Net.Mail.MailAddress(email.Text);
m.Subject = "Contact us form submisson";
m.Headers.Add("Reply-To", "your email account");
System.Net.Mail.SmtpClient s = new System.Net.Mail.SmtpClient();
s.UseDefaultCredentials = false;
s.Credentials = c;
s.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
s.EnableSsl = true;
s.Port = 587;
s.Host = "smtp.gmail.com";
s.Send(m);
lblCorrectCode.Text = "Contact Form Has been submited we will be in touch shortly";
name.Text = string.Empty;
phone.Text = string.Empty;
email.Text = string.Empty;
message.Text = string.Empty;
I surly hope you are not populate it in page load and not checking isPostBack
try
{
s.Send(m);
}
finally
{
lblCorrectCode.Text = "Contact Form Has been submited we will be in touch shortly";
name.Text = string.Empty;
phone.Text = string.Empty;
email.Text = string.Empty;
message.Text = string.Empty;
}

Categories

Resources