See title. Since SmtpClient.Send has no return value, I want to know how I can be sure that the E-Mail was successfully sent.
Here is the code I have until now and it works fine (it is from google):
private void sendMail(string strToAddress, string strFromAddress, string strSubject, string strBody)
{
// new instance of MailMessage
MailMessage mailMessage = new MailMessage();
// Sender Address
mailMessage.From = new MailAddress(strFromAddress);
// Recepient Address
mailMessage.To.Add(new MailAddress(strToAddress));
// Subject
mailMessage.Subject = strSubject;
// Body
mailMessage.Body = strBody;
// format of mail message
mailMessage.IsBodyHtml = true;
// new instance of Smtpclient
SmtpClient mailSmtpClient = new SmtpClient("mail.lablabal.com");
// mail sent
mailSmtpClient.Send(mailMessage);
}
If there's an immediate error, SmtpClient::Send() will throw an exception. There's no way to "track" the email (unless there's some confirmation link to click or whatever). You won't keep a server connection till the mail is received, only till your smtp server passed it successfully (or failed doing so).
Related
First of all, my apologies if this is a duplicate question. I have searched for it a lot, but couldn't find related issues.
So here's the problem: I am using SmtpClient and MailMessage class to send mails. I am passing the subject of the mail as a parameter in the mail sending method. First time the mail is sent with the proper subject (the one i sent as parameter). However, in all next emails, no matter what subject i put, the subject remains the same (the one used first time). The subject is set from inside of the method.
(Note: This is a WindowsForm application)
What i have tried is, creating another method named "Refresh()" which disposes the mail object and creates it again (with from and to info only). And call this method each time after a mail is sent. But it doesn't help with this problem.
Codes are given below:
Fields:
MailMessage message;
SmtpClient mailer;
string from = "sender email";
string pass = "sender pass";
string to = "rec email";
Constructor:
try
{
message = new MailMessage(from, to);
mailer = new SmtpClient("smtp.gmail.com", 587);
mailer.Credentials = new NetworkCredential(from, pass);
mailer.EnableSsl = true;
}
catch(Exception ex) { /*code to write log*/ }
Refresh method:
void RefreshMessage()
{
try
{
message.Subject = "";
message.Dispose();
message = new MailMessage(from, to);
}
catch(Exception ex) { /*write log*/ }
}
Method which is sending the mail:
internal void TextOnly(string sub, string bodyMessage)
{
try
{
message.Subject = sub;
message.Body = bodyMessage;
mailer.Send(message);
this.RefreshMessage();
}
catch (Exception ex) { /*write log*/ }
}
Example of how it's called:
m.TextOnly("Subject 1" , SomeStringMethod());
m.TextOnly("Another Title " + anyString, "Some string mail");
m.TextOnly("[TAG] Email subject goes here" , AnotherStringMethod());
Now no matter whatever subject is sent in the parameter, it will always send with subject "Subject 1" (from the example above). The body of the message is fine, only the subject is not right.
I have few other methods in the class (for other purposes like sending mails with attachments for example), where subject isn't passed as parameter but it's set directly from within the method (like message.Subject = "Example Sub" from within the method), in that case it works fine.
But in the case above, where the subject is passed to the method, the subject remains the same.
Like the comment section already stated, there is no reason to cache the message itself. Currently, you're disposing the message(which actually puts it in a unusable state) and then you recreate it. Check out more HERE. You can just as well simply create new objects and dispose of them after you're done so the Garbage Collector can release the resources as soon as possible.
Just utilize a simple method for constructing MailMessages and send them directly.
internal MailMessage ConstructTextMailMessage(MailAddress from, MailAddress to, string subject, string body)
{
return ConstructTextMailMessage(from.Address, to.Address, subject, body);
}
internal MailMessage ConstructTextMailMessage(string from, string to, string subject, string body)
{
return new MailMessage(from, to, subject, body);
}
And then:
var mailClient = new SmtpClient("smtp.gmail.com", 587);
mailClient.Credentials = new NetworkCredential(from, pass);
mailClient.EnableSsl = true;
mailClient.Send(ConstructTextMailMessage(from, to, "Subject 1", SomeStringMethod()));
mailClient.Send(ConstructTextMailMessage(from, to, "Another Title " + anyString, "Some string mail");
mailClient.Send(ConstructTextMailMessage(from, to, "[TAG] Email subject goes here", AnotherStringMethod());
If you have attachments in the MailMessage, you should call Dispose after using them to clear up the streams. Also, call Dispose on the SmtpClient when you're done using it.
I used the same functionality (SntpClient, MailMessage etc.) in one of my programms and it worked just fine:
SmtpClient client = new SmtpClient("host", port);
MailMessage mail;
MailAddress absender = new MailAddress("mail#adress.from");
foreach (string sub in Subjects)
{
mail = new MailMessage();
mail.IsBodyHtml = true;
mail.Subject = sub;
mail.From = absender;
mail.To.Add("mail#adress.to");
client.Send(mail);
}
Mybe you just need to make a new MailMessage-Object each time you "create" a E-Mail.
Is there any way to configure forward-to email address like replyto in System.Net.Mail.MailMessage?
If not then is there any way I can achieve that?
No, there is not.
The reason is that there is no such field defined in an email. You can see the defined fields here.
So this is not a matter of C# API, there is no way to do what you want to do, not in C# and not in other languages/frameworks.
You can do this only by doing it via Outlook (using interop)
var newItem = mailItem.Forward();
newItem.Recipients.Add("test#test.be");
newItem.Send();
the .Forward() is described here
There's no 'forwardto' in MailMessage (that's up to the user receiving the mail).
But you can send to multiple receipients at once, using either the CC or the BCC properties.
Here's an axample using CC:
public static void CreateCopyMessage(string server)
{
MailAddress from = new MailAddress("ben#contoso.com", "Ben Miller");
MailAddress to = new MailAddress("jane#contoso.com", "Jane Clayton");
MailMessage message = new MailMessage(from, to);
// message.Subject = "Using the SmtpClient class.";
message.Subject = "Using the SmtpClient class.";
message.Body = #"Using this feature, you can send an email message from an application very easily.";
// Add a carbon copy recipient.
MailAddress copy = new MailAddress("Notification_List#contoso.com");
message.CC.Add(copy);
SmtpClient client = new SmtpClient(server);
// Include credentials if the server requires them.
client.Credentials = CredentialCache.DefaultNetworkCredentials;
Console.WriteLine("Sending an email message to {0} by using the SMTP host {1}.",
to.Address, client.Host);
try {
client.Send(message);
}
catch (Exception ex) {
Console.WriteLine("Exception caught in CreateCopyMessage(): {0}",
ex.ToString() );
}
}
Now you can send to more than one, which Works like auto forwarding.
I have create function to send an email. This function was work successful on localhost but on server its failed without any exception. I know the problem comes from my Port on IP Address.
The sample body is string body = "<p>Please click here</p>Thank You."
The problem is : between IP Address and Port.
Successful send an email if i remove :.
Do you guys have any ideas?
public void Sent(string sender, string receiver, string subject, string body)
{
using (MailMessage mail = new MailMessage(sender, receiver))
{
using (SmtpClient client = new SmtpClient())
{
client.Port = 25;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.Host = "mail.companyName.com.my";
mail.Subject = subject;
mail.IsBodyHtml = true;
mail.Body = body;
client.Send(mail);
}
}
}
You are doing it right, the code to send the mail is ok (you may want to revise the function name and make the smtp host name configurable, but that is not the point here).
The e-mail delivery fails on a relay, there is no immedieate feedback (no exception) to the client about this kind of failure.
The best bet is the IncreaseScoreWithRedirectToOtherPort property set in Set-HostedContentFilterPolicy in case your mail provider is Office365, or a similar spam filter mechanism in any other mail provider that is encountered down the mail delivery chain.
You can set a reply-to address and hope that the destination server will bounce a delivery failure that gives you more information. Or have the admin of the mail server look up the logs. More information here:
https://serverfault.com/questions/659861/office-365-exchange-online-any-way-to-block-false-url-spam
Try setting the 'mail.Body' to receive a Raw Html message instead of a encoded string, like:
mail.Body = new System.Web.Mvc.HtmlHelper(new System.Web.Mvc.ViewContext(), new System.Web.Mvc.ViewPage()).Raw(body).ToString();
Or put a using System.Web.Mvc at the beginning so it gets shorter and easier to understand:
using System.Web.Mvc
mail.Body = new HtmlHelper(new ViewContext(), new ViewPage()).Raw(body).ToString();
I am working with C# and I am trying to send an email form a web page. I am trying to populate the from email address from a textbox and the to email address is being hard coded. My code is as follows and the errors I am getting are after the code.
try
{
MailMessage oMsg = new MailMessage();
// TODO: Replace with sender e-mail address. Get from textbox: string SenderEmail = emailbox.text
oMsg.From = emailbox.Text; //Senders email
// TODO: Replace with recipient e-mail address.
oMsg.To = "DummyRecipient#gmail.com"; //Recipient email
oMsg.Subject = subjecttbox.Text; //Subject of email
// SEND IN HTML FORMAT (comment this line to send plain text).
//oMsg.BodyFormat = MailFormat.Html;
// HTML Body (remove HTML tags for plain text).
oMsg.Body = EmailBody; //Body of the email
// ADD AN ATTACHMENT.
// TODO: Replace with path to attachment.
//String sFile = #"C:\temp\Hello.txt";
//MailAttachment oAttch = new MailAttachment(sFile, MailEncoding.Base64);
//oMsg.Attachments.Add(oAttch);
// TODO: Replace with the name of your remote SMTP server.
SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
//SmtpMail.SmtpServer = "Smtp.gmail.com"; //Email server name, Gmail = Smtp.gmail.com
SmtpServer.Port = 587;
SmtpServer.Credentials = new System.Net.NetworkCredential("DummySenderAddress#gmail.com", "DummyPassword");
SmtpServer.EnableSsl = true;
SmtpMail.Send(oMsg);
oMsg = null;
//oAttch = null;
}
catch //(Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
}
Cannot implicitly convert type 'string' to
'System.Net.Mail.MailAddress' Property or indexer
'System.Net.Mail.MailMessage.To' cannot be assigned to -- it is read
only
Cannot implicitly convert type 'string' to
'System.Net.Mail.MailAddressCollection' The name 'SmtpMail' does not
exist in the current context
The problem is in your line:
oMsg.To = "DummyRecipient#gmail.com"; //Recipient email
Emails can have more than one recipient. Therefore the "To" property of the MailMessage class is a collection. Not a single email address.
Additionally, you need to create a MailAddress object instead of just using a string for the email.
Use the following line instead of the above.
oMsg.To.Add(new MailAddress("DummyRecipient#gmail.com")); //Recipient email
oMsg.From takes a MailAddress object as its input, not a string. Replace it with:
oMsg.From = new MailAddress(emailbox.Text);
oMsg.To takes a MailAddressCollection as its input. Assuming that collection isn't null, you should be able to replace it with:
oMsg.To.Add("DummyRecipient#gmail.com");
I have a code for sending email through code, its as follows:
string subject = "SecureEmail: URS Scheduler - ";
string body = #"Message: My Message";
try
{
SmtpClient sm = new SmtpClient();
MailMessage msg = new MailMessage();
//msg.SubjectEncoding.
sm.Host = "email.myhost.com";
//Add Sender
msg.From = new MailAddress("abc#myhost.com");
//Add reciepents
sendMailToUsers(msg, "pqr#myhost.com");
//send message
msg.IsBodyHtml = true;
msg.Subject = subject;
msg.Body = body;
sm.Send(msg);
I am able to send message but its not encrypted, its a plain Text.
When I go to my Outlook mail client and Send Mail with above recipients and body, and subject starting with "SecureEmail:", I get an Encrypted Email with a button "Open Message". When I click on Open Message it redirects me to https://web1.zixmail.net/s/e?b=domain&m=encrypted msg and other info,then I login into it and and able to see the plain text of mail body.
Please help me in getting above behaviour through my code.
Your company is using ZixMail, and your Outlook has a plugin to enable this. If you want to send ZixMail from C#, you'll need to use their toolset and API. Reffer to ZixMail documentation and support.