Sanity check of an email implementation please :-) Anything obvious I've missed?
string supplierOfThisMaterialEmailAddress = "davexxx#gmail.com"; // TODO
string htmlBodyIncludingReplacements = "<html><head><title>E-mail</title></head><body><div>. There has been a request on the hello.co.nz website for: " + txtMaterialDescription.Text +
"<br />Full Name: <b>" + fullName + "</b><br />" +
etc..";
string textOnlyBodyIncludingReplacements = "E-mail. There has been a request on the freematerials.co.nz website for: " + txtMaterialDescription.Text +
"Full Name: " + fullName +
"etc..";
string subject = "Someone has contacted you";
CustomMailer mailer = new CustomMailer();
string result = mailer.SendEmail(subject, htmlBodyIncludingReplacements, supplierOfThisMaterialEmailAddress, textOnlyBodyIncludingReplacements);
if (result != null)
lblMessage.Text = result;
else
lblMessage.Text = "Thank you - email has been sent";
And the class:
public class CustomMailer
{
public string SendEmail(string subject, string htmlBodyIncludingReplacements, string emailTo, string textOnlyBodyIncludingReplacements)
{
try
{
MailAddress sender = new MailAddress("dave#hello.co.nz", "Dave Mateer");
emailTo = "dave#hello.co.nz"; // testing
MailAddress recipient = new MailAddress(emailTo, null);
MailMessage message = new MailMessage(sender, recipient);
message.Subject = subject;
AlternateView textView = AlternateView.CreateAlternateViewFromString(textOnlyBodyIncludingReplacements, null, "text/plain");
AlternateView htmlView = AlternateView.CreateAlternateViewFromString(htmlBodyIncludingReplacements, null, MediaTypeNames.Text.Html);
message.AlternateViews.Add(textView);
message.AlternateViews.Add(htmlView);
SmtpClient client = new SmtpClient();
client.Send(message);
}
catch (Exception ex)
{
throw new Exception();
}
return null;
}
}
At first glance, catching a general Exception object and throwing a new one is going to have the net effect of eating any exceptions thrown by SendEmail.
The rest looks okay.
You should change the
catch (Exception ex)
{
throw new Exception();
}
to :
catch (Exception ex)
{
throw;
}
because otherwise you lose all the data that came with the original excepion that was thrown
Related
We have an old program which i believe is built using C# for which i have the source code but i cannot edit the program. The issue is we have moved our email to a new provider who is using STARTTLS for sending emails and our program is now failing to send a simple email and returning the error below;
sendemail - Error in processing. The server response was: 5.7.3 STARTTLS is required to send mail [LO4P123CA0676.GBRP123.PROD.OUTLOOK.COM]
We have an XML file which we can change the values of but i cannot see anywhere to add anything to allow the STARTTLS to work.
The XML file contains the following;
<Sage200_ImportSLsettings>
<FileLocation>
<FileLocation>D:\Sage\Sage Import Files</FileLocation>
<Company>Volmary Ltd</Company>
<MailServer>smtp-mail.outlook.com</MailServer>
<MailTo>email</MailTo>
<MailFrom>email</MailFrom>
</FileLocation>
</Sage200_ImportSLsettings>
The C# code is shown below (which we are not able to edit)
private void ReadXMLforConnectionDetails()
{
try
{
string path = Path.GetDirectoryName(Application.ExecutablePath) + #"\#CPS_Sage200_SLImport.xml";
if (File.Exists(path))
{
IEnumerator enumerator;
XmlDocument document = new XmlDocument();
document.Load(path);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable);
XmlNodeList list = document.DocumentElement.SelectNodes("/Sage200_ImportSLsettings/FileLocation", nsmgr);
try
{
XmlNode current;
enumerator = list.GetEnumerator();
goto TR_0018;
TR_0008:
try
{
this.MailFrom = current["MailFrom"].InnerText;
}
catch (Exception exception5)
{
ProjectData.SetProjectError(exception5);
this.MailFrom = "";
ProjectData.ClearProjectError();
}
goto TR_0018;
TR_000B:
try
{
this.MailTo = current["MailTo"].InnerText;
}
catch (Exception exception4)
{
ProjectData.SetProjectError(exception4);
this.MailTo = "";
ProjectData.ClearProjectError();
}
goto TR_0008;
TR_000E:
try
{
this.MailServer = current["MailServer"].InnerText;
}
catch (Exception exception3)
{
ProjectData.SetProjectError(exception3);
this.MailServer = "";
ProjectData.ClearProjectError();
}
goto TR_000B;
TR_0011:
try
{
this.SageCompany = current["Company"].InnerText;
}
catch (Exception exception2)
{
ProjectData.SetProjectError(exception2);
this.SageCompany = "";
ProjectData.ClearProjectError();
}
goto TR_000E;
TR_0018:
while (true)
{
if (enumerator.MoveNext())
{
current = (XmlNode) enumerator.Current;
try
{
this.FileLocation = current["FileLocation"].InnerText;
}
catch (Exception exception1)
{
ProjectData.SetProjectError(exception1);
this.FileLocation = "";
ProjectData.ClearProjectError();
}
}
else
{
this.ConnecttoSage200();
return;
}
break;
}
goto TR_0011;
}
finally
{
if (enumerator is IDisposable)
{
(enumerator as IDisposable).Dispose();
}
}
}
this.WritetoErrorLog("ReadXMLforConnectionDetails() - File does not exist. " + path);
Application.Exit();
}
catch (Exception exception6)
{
Exception ex = exception6;
ProjectData.SetProjectError(ex);
Exception exception = ex;
this.WritetoErrorLog("ReadXMLforConnectionDetails() - " + exception.Message);
Application.Exit();
ProjectData.ClearProjectError();
}
}
private void sendemail(string MailSubject, string Emailbody)
{
try
{
MailMessage message = new MailMessage();
SmtpClient client = new SmtpClient(this.MailServer);
message.From = new MailAddress("\"CPS - Sage200 SL Import\"<" + this.MailFrom + ">");
message.To.Add(new MailAddress(this.MailTo));
message.Subject = MailSubject;
message.IsBodyHtml = false;
message.Body = Emailbody;
client.Credentials = new NetworkCredential("email", "password");
client.Send(message);
message.Dispose();
}
catch (Exception exception1)
{
Exception ex = exception1;
ProjectData.SetProjectError(ex);
Exception exception = ex;
this.WritetoErrorLog("sendemail - " + exception.Message);
Application.Exit();
ProjectData.ClearProjectError();
}
}
Any advice will be greatly appreciated.
There is no logic in that code to configure the SmtpClient to use STARTTLS so there is no possible XML tag you can add to make it use it.
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'/>
public void AccessOutlook()
{
Application oOutlook;
NameSpace oNs;
MAPIFolder oFldr;
try
{
oOutlook = new Application();
oNs = oOutlook.GetNamespace("MAPI");
oFldr = oNs.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
string str = "Total Mail(s) in Inbox:" + oFldr.Items.Count;
string str2 = "Total Unread items = " + oFldr.UnReadItemCount;
foreach (var oMessage in oFldr.Items)
{
MailItem mitem = null;
try
{
if (oMessage != null)
{
mitem = (MailItem)oMessage;
String savepath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\" + "Sridhar.html";
mitem.BodyFormat = OlBodyFormat.olFormatHTML;
mitem.SaveAs(savepath, OlSaveAsType.olHTML);
}
}
catch (System.Exception ex)
{
}
if (mitem != null)
{
string str3 = mitem.Subject;
}
}
}
catch (System.Exception ex)
{
}
finally
{
GC.Collect();
oFldr = null;
oNs = null;
oOutlook = null;
}
}
Here I want to convert mail item into PDF, hence in first step I'm trying to get mail item based on subject line and saving it in any outlook supported file formats. But I'm not able to do. Can anyone help with this?
Thanks in advance
I'm having a problem with email sending in C#.
I'm working on an add-in and everything is going well. I can send my mails, like i want, but not "two times in a row".
For example, my add-in open a Form and after the user action an email is sent.
When the mail is sent, the form is closed and that's okay.
But some time, i need to send two separate emails and the body of second email is always empty. By the way, i fill the "body" of my mails with Word (Microsoft.Office.Interop.Word) to have some formatted text.
If I use the .Body property there is no problem.
Now, I'm wondering if it's not the fault of "Word" because the email part is working but only the body is empty.
I tried to send my mails in the inverse order to see if it's occurs always with the second mail and i was right. It's not about the email or his content but more about being the second sent.
It may be some things which haven't been released yet(not properly released objects) or something like that but i'm doing already it.
That's how i'm doing..
Outlook.MailItem mailItem = (Outlook.MailItem)new Outlook.Application().CreateItem(Outlook.OlItemType.olMailItem);
try
{
mailItem.CC = currentUserExchange.PrimarySmtpAddress;
mailItem.Importance = Outlook.OlImportance.olImportanceHigh;
mailItem.Subject = "XXX";
mailItem.To = finalRecipients;
fillBody(mailItem, mailBody);
mailItem.Send();
}
catch (Exception ex) { }
finally
{
releaseObject(mailItem);
}
if (moderatorPin != String.Empty)
{
Outlook.MailItem mailItemSecurity = (Outlook.MailItem)new Outlook.Application().CreateItem(Outlook.OlItemType.olMailItem);
try
{
mailItemSecurity.Importance = Outlook.OlImportance.olImportanceHigh;
mailItemSecurity.Subject = "XXX";
mailItemSecurity.To = currentUserExchange.PrimarySmtpAddress;
fillBody(mailItemSecurity, mailBodySecure);
mailItemSecurity.Send();
}
catch (Exception ex) { MessageBox.Show("error : " + ex.Message); }
finally
{
releaseObject(mailItemSecurity);
}
}
and :
private void fillBody(Outlook.MailItem mailItem, String bodyMail)
{
Word.Document document = mailItem.GetInspector.WordEditor;
Word.Range rng = document.Paragraphs[1].Range;
try
{
document.Paragraphs[1].LineSpacingRule = Word.WdLineSpacing.wdLineSpaceSingle;
rng.set_Style(Word.WdBuiltinStyle.wdStyleHtmlKbd);
rng.Font.Color = (Word.WdColor)(fontColor.R + 0x100 * fontColor.G + 0x10000 * fontColor.B);
rng.Text = bodyMail;
rng.Select();
}
catch (Exception ex)
{
MessageBox.Show("XXX");
}
finally
{
releaseObject(rng);
releaseObject(document);
}
}
I have here a bunch of code regarding SMTPClient Send mail:
public void SendEmailToCustomer(ReservationDetails reservationDetails, string reason, string cardtype) {
MailMessage msg = new MailMessage(ConfigurationManager.AppSettings["Email.Sender"], reservationDetails.Email);
msg.Subject = this.Subject;
msg.Body = this.Body.Replace("[InvoiceNumber]", reservationDetails.Invoice)
.Replace("[GuestName]", reservationDetails.Name)
.Replace("[GuestTelephone]", reservationDetails.Telephone)
.Replace("[GuestEmail]", reservationDetails.Email)
.Replace("[GuestAddress]", reservationDetails.Address)
.Replace("[GuestCompany]", reservationDetails.CompanyName)
.Replace("[GuestCompanyAddress]", reservationDetails.CompanyAddress)
.Replace("[GuestCompanyNumber]", reservationDetails.CompanyNumber)
.Replace("[OtherRemarks]", reservationDetails.Other)
.Replace("[TransferDescription]", reservationDetails.TransferDescription)
.Replace("[FlightArrivalDate]", reservationDetails.ArrivalDate)
.Replace("[ETA]", reservationDetails.ETA)
.Replace("[FlightArrival]", reservationDetails.FlightArrival)
.Replace("[FlightDepartureDate]", reservationDetails.DepartureDate)
.Replace("[ETD]", reservationDetails.ETD)
.Replace("[FlightDeparture]", reservationDetails.FlightDeparture)
.Replace("[NoOfNights]", reservationDetails.NoOfNights)
.Replace("[CheckIn]", reservationDetails.CheckIn)
.Replace("[CheckOut]", reservationDetails.CheckOut)
.Replace("[RoomName]", reservationDetails.RoomName)
.Replace("[Qty]", reservationDetails.Qty)
.Replace("[RoomAmount]", String.Format("{0:N}", Convert.ToDecimal(reservationDetails.RoomAmount)))
.Replace("[RateRoom]", String.Format("{0:N}", Convert.ToDecimal(reservationDetails.RateRoom)))
.Replace("[NumExtra]", Convert.ToString(reservationDetails.NumExtra))
.Replace("[ExtraAmount]", String.Format("{0:N}", Convert.ToDecimal(reservationDetails.ExtraAmount)))
.Replace("[RateExtra]", String.Format("{0:N}", Convert.ToDecimal(reservationDetails.RateExtra)))
.Replace("[RTTQty]", Convert.ToString(reservationDetails.RTTQty))
.Replace("[RTT]", String.Format("{0:N}", Convert.ToDecimal(reservationDetails.RTT)))
.Replace("[RTTAmount]", String.Format("{0:N}", Convert.ToDecimal(reservationDetails.RTTAmount)))
.Replace("[TotalAmount]", String.Format("{0:N}", Convert.ToDecimal(reservationDetails.TotalAmount)))
.Replace("[ModePay]", reservationDetails.ModePayment)
.Replace("[Reason]", "Reason: " + reason)
.Replace("[CardType]", cardtype)
;
msg.CC.Add(this.AddressCC);
msg.Bcc.Add(this.AddressBCC);
msg.IsBodyHtml = true;
try {
SmtpClient client = new SmtpClient(ConfigurationManager.AppSettings["Smtp.Client"]);
client.Credentials = new System.Net.NetworkCredential(ConfigurationManager.AppSettings["Smtp.Credentials.Username"], ConfigurationManager.AppSettings["Smtp.Credentials.Password"]);
client.Send(msg);
} catch (Exception ex) {
//Do nothing
//throw new Exception("Couldn't send email: <p>" + ex.Message);
} finally {
msg.Dispose();
}
}
It takes too long to send an email (approx. 5 seconds).
I also disposed MailMessage.
What could be the possible cause of the email delay. And how can I resolve the issue?
Many thanks!! :D