I'm using System.Net.Mail to send email in my application but I get an exception and I can't figure out what/where the problem is and how to fix it.
The error says I have some invalid char:
An invalid character was found in the mail header: ';'.
I tried google without success.
The string with email address is:
john#mydomain.org; beth#mydomain.org; alfred#mydomain.org; barbie#mydomain.org;
Here is my email sending code:
SmtpClient smtpClient = new SmtpClient("smtp.........");
System.Net.Mail.MailMessage mailMessagePlainText = new System.Net.Mail.MailMessage();
mailMessagePlainText.IsBodyHtml = true;
mailMessagePlainText.From = new MailAddress("vincent#mydomain.org", "admin");
mailMessagePlainText.Subject = "test";
mailMessagePlainText.Body = "test";
mailMessagePlainText.To.Add(new MailAddress(List1.ToString(), ""));
mailMessagePlainText.Bcc.Add(new MailAddress("vincent#mydomain.org", ""));
try
{
smtpClient.Send(mailMessagePlainText);
}
catch (Exception ex)
{
throw (ex);
}
foreach (var address in List1.split(';')) {
mailMessagePlainText.To.Add(new MailAddress(address.Trim(), ""));
}
Because according to your string here above, each address in this loop above would produce following:
"john#mydomain.org"
" beth#mydomain.org"
" alfred#mydomain.org"
" barbie#mydomain.org"
So by adding .Trim() to address would make your code work.
A MailAddressCollection (like your mailMessagePlainText.To) has an Add method that accepts a string containing a list of mail addresses, separated by a comma.
So to use that, you will need to change the ; into a , and possibly remove the extra spaces.
It looks like you're adding the addresses as a single MailAddress, where you need to add them 1 at a time. I don't know what other overloads are available, but the following will probably work.
I split the string by ; and add each address separately.
replace
mailMessagePlainText.To.Add(new MailAddress(List1.ToString(), ""));
with
foreach (var address in List1.split(';')) {
mailMessagePlainText.To.Add(new MailAddress(address , ""));
}
Related
Hi I am working on a bulk email sending feature. Below is my loop that validates email and sends them to each recipient:
foreach (var userID in recipientUserIds)
{
var userInfo = //getting from database using userID.
try
{
to = new MailAddress(userInfo.Email1, userInfo.FirstName + " " + userInfo.LastName);
}
catch (System.FormatException fe)
{
continue;
}
using (MailMessage message = new MailMessage(from, to))
{
//populate message and send email.
}
}
Since the recipientUserIds is always more than 2000, using try-catch seems to be very expensive for each user in this case just to validate the email address format. I was wondering to use regex, but not sure if that will help with performance.
So my question is if there is any better or performance optimized way to do the same validation.
Validating email addresses is a complicated task, and writing code to do all the validation up front would be pretty tricky. If you check the Remarks section of the MailAddress class documentation, you'll see that there are lots of strings that are considered a valid email address (including comments, bracketed domain names, and embedded quotes).
And since the source code is available, check out the ParseAddress method here, and you'll get an idea of the code you'd have to write to validate an email address yourself. It's a shame there's no public TryParse method we could use to avoid the exception being thrown.
So it's probably best to just do some simple validation first - ensure that it contains the minimum requirements for an email address (which literally appears to be user#domain, where domain does not have to contain a '.' character), and then let the exception handling take care of the rest:
foreach (var userID in recipientUserIds)
{
var userInfo = GetUserInfo(userID);
// Basic validation on length
var email = userInfo?.Email1?.Trim();
if (string.IsNullOrEmpty(email) || email.Length < 3) continue;
// Basic validation on '#' character position
var atIndex = email.IndexOf('#');
if (atIndex < 1 || atIndex == email.Length - 1) continue;
// Let try/catch handle the rest, because email addresses are complicated
MailAddress to;
try
{
to = new MailAddress(email, $"{userInfo.FirstName} {userInfo.LastName}");
}
catch (FormatException)
{
continue;
}
using (MailMessage message = new MailMessage(from, to))
{
// populate message and send email here
}
}
I need to send an email containing a string like this:
CSAclsEN\t001\t\\\\sgprt\\Projects2\t001\tCSAclsEN-2010-1140609\t10:03\t09JUN14\t2010\tNorth London branch\tGG02\t001\t****09\tCustomer 340509\t\r01\t******35 \tVariable rate Cash ISA\tGBP\t395.08\t\r02\t31MAR14\tInterest\t7.21+\t\t\r01\t******69 \tInstant Access account\tGBP\t0.00\t\r01\t******75 \t35 Day Notice account\tGBP\t412.11\t\r02\t27MAY14\tInterest\t0.22+\t\t\r02\t25APR14\tInterest\t0.21+\t\t\r02\t25MAR14\tInterest\t0.19+\t\t\r02\t25FEB14\tInterest\t0.21+\t\t\r02\t27JAN14\tInterest\t0.28+\t\t\r01\t******76 \t35 Day Notice account\tGBP\t0.00\t
(this is that it can be investigated in the same format it is taken off of the WebSpehere Message Queue.
Unfortunately the SMTP Mail seems to be taking that and turning it into this:
Here is my code:
SmtpClient emailSender;
MailMessage theMessage;
// Connect to the server.
emailSender = new SmtpClient("sgexc");
// Build the content details.
theMessage = new MailMessage();
theMessage.From = new MailAddress(emailFromAddress, "Cashier Printing System");
theMessage.Subject = emailSubject;
string[] toAddresses = emailToAddress.Split(new Char[] { ':' });
foreach (string toAddress in toAddresses)
{
theMessage.To.Add(toAddress);
}
string[] ccAddresses = emailCCAddress.Split(new Char[] { ':' });
//foreach (string ccAddress in ccAddresses)
// {
// theMessage.CC.Add(ccAddress);
// }
sMessage=sMessage.Replace(#"\","\\");
theMessage.Body = sMessage;
theMessage.IsBodyHtml = false;
// Fill in the details and send.
emailSender.Send(theMessage);
WHat do I need to do if I want to prevent Outlook or SMTP from parsing those escape sequences? I have tried replacing all the backslashes with 2 backslashes but no luck.
I found the answer, and it's very simple.
I just set the theMessage.IsBodyHtml = true;
I'm generating a simple email using the System.Net.Mail.MailMessage class and building the body with a StringBuilder. I'm looping through a string[] and trying to append a new line each time. The problem I'm having is that I can't seem to generate a single new line each time. I can either get two or none.
What I've tried:
foreach (var message in messages)
{
body.AppendLine(message);
}
foreach (var message in messages)
{
body.Append(message + "\n");
}
foreach (var message in messages)
{
body.Append(message + System.Environment.NewLine);
}
I've also tried with string.Format().
For each example above, I get the same result. No new line being generated.
When I try the following, however, I get the expected result. A new line with an empty line in between.
foreach (var message in messages)
{
body.AppendLine(message + System.Environment.NewLine);
}
Why is it doing this and what can I do to just get a single new line each time?
Update:
So I've found that Outlook and probably Gmail (haven't tested others) are actually removing some line breaks and not others. Does anyone know why or how they determine what to remove?
When I checked the email in Outlook, I got a tiny info message saying "Extra line breaks in this message were removed" and the option to restore them. Gmail gave no such indication (that I found) but I must assume it removed them as well.
Interestingly enough I had line breaks elsewhere in the body that worked as expected, only the ones in the loop were deemed "extra".
I have modified my code to build the email body using html.
IsBodyHtml = true
If anyone knows of a way to prevent this, or what causes certain line breaks to be removed, please let me know.
Update:
Once I knew what I was looking for, I found this post which helps to explain things and gives some alternate solutions. I did not try any of them, as I think using html is the better solution in my case.
I have just ran this through LINQPad
string[] messages = new string[]{"First line in message", "Second Line in message", "Third Line in message"};
StringBuilder sbA = new StringBuilder();
StringBuilder sbB = new StringBuilder();
StringBuilder sbC = new StringBuilder();
StringBuilder sbD = new StringBuilder();
// New line for each string
foreach (var message in messages)
{
sbA.AppendLine(message);
}
// New line for each string
foreach (var message in messages)
{
sbB.Append(message + "\n");
}
// New line for each string
foreach (var message in messages)
{
sbC.Append(message + System.Environment.NewLine);
}
//One Line
foreach (var message in messages)
{
sbD.Append(message);
}
sbA.Dump();
sbB.Dump();
sbC.Dump();
sbD.Dump();
Each one performs as expected in a StringBuilder sense.
I suspect that you need to add "</br>" at the end of each AppendLine something like this (not tested):
MailMessage mail = new MailMessage(new MailAddress("someSender#email.com"), new MailAddress("someReceiver#email.com"));
string[] messages = new string[]{"First line in message", "Second Line in message", "Third Line in message"};
StringBuilder body = new StringBuilder();
body.AppendLine("<h2>My Message<h2></br>" );
foreach (var message in messages)
{
body.AppendLine(message + "</br>");
}
mail.Body = body.ToString();
mail.Dump();
Gmail will remove explicit line breaks. This code works for me when sending to Gmail, as well as Outlook with proper line breaks intact. I am completely unable to replicate your issue without seeing what your messages[] array looks like. It may be possible that some formatting could be viewed as line breaks causing all to be stripped out? I have tampered with my example strings and I cannot get Outlook nor Gmail to strip the line breaks on me.
private void SendMessage()
{
try
{
StringBuilder body = new StringBuilder();
string[] messages = { "test with a tab in it", " test with spaces", " \r\nTab, then line break", "\n\n\n\n\n\nlots of returns...", " test spaces" };
foreach (var msg in messages)
{
body.AppendLine(msg);
//body.AppendLine(string.Empty);
}
using (MailMessage message = new MailMessage())
{
message.From = new MailAddress("you#test.com", "Your Display Name");
message.ReplyToList.Add("reply-email#test.com");
message.To.Add("to#test.com");
message.Subject = "Test Line Break Message";
message.IsBodyHtml = false;
message.Priority = MailPriority.Normal;
message.BodyEncoding = System.Text.Encoding.UTF8;
message.Body = body.ToString();
using (SmtpClient smtpClient = new SmtpClient())
{
smtpClient.Host = "127.0.0.1";
smtpClient.Send(message);
}
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
I am going to assume somewhere in your code that builds or retrieves the messages array, something is happening to cause this issue. I would believe it to be fixable, but not without seeing how that part is coded.
string line;
int counter = 0;
do
{
line = readFile.ReadLine();
counter++;
var emailAddress = line;
if (line != null)
{
Console.WriteLine("Reading client email address...");
mailMessage.From = new MailAddress("myEmailAddress");
mailMessage.To.Add(line);
mailMessage.Subject = "TEST_SUBJECT";
mailMessage.Body = "TEST_BODY";
client.EnableSsl = true;
client.Send(mailMessage);
Console.WriteLine("Email sent to: " + line);
}
} while (line != null);
The problem is, whenever the app sends an email, it iterates again trough the source (the file where are stored the emails) and it goes like:
Read lines > Send email to line 1 > Read lines > Send email to line 1 & line 2 > Read lines > Send emails to line 1, 2 & 3 and so on. It doesn't go like it's supposed to: Read lines > Send email to line 1 > Send email to line 2.
What I'm doing wrong?
The problem is this line:
mailMessage.To.Add(line);
With each iteration, you ADD anoter email address to the message, wich causes your problem.
try something like:
mailMessage.To.Clear();
mailMessage.To.Add(line);
or initialize a new mailMessage object in each iteration.
I think you should init mailMessage with new in the loop.
Your problem is with the line:
mailMessage.To.Add(line);
You are adding a new recipient to the message, but not getting rid of old ones from previous iterations.
Assuming you're using System.Net.Mail.MailMessage, To is a MailAddressCollection type so you should be able to clear old entries using:
mailMessage.To.Clear();
This is my mail sending code. I was getting "There is Invalid character in Mail Header" error.When i changed my Computer Name some shortest name. The problem solved. But in my domain whole computer names like "04500-ab04545.xxxdomain.gov.tr" so I need to find another solution for this problem.
So I cant give a static computer name while sending mail from c# code.
MailMessage msg = new MailMessage();
msg.Body = "axxxxxx";
msg.To.Add(new MailAddress("xxxx#xxxx.domain"));
msg.From = new MailAddress("xxxx#xxxx.domain","blab blalb");
msg.Subject = "Subject xxx";
SmtpClient server = new SmtpClient("xxxxxxxx",25);
server.Credentials = new NetworkCredential("xxxxx", "xxxxxxx");
SmtpClient server = new SmtpClient("mail.adalet.gov.tr",25);
server.Credentials = new NetworkCredential("xxx", "xxx");
server.Send(msg);
I suspect this might be an Encoding related issue.
Try using the new MailAddress("xxxx#xxxx.domain","blab blalb", Encoding.Default) constructor.
Else try Encoding.Unicode.
Update:
After some digging, this exception is thrown from:
void System.Net.BufferBuilder.Append(string,int,int);
This will happen if you have any characters above \xff in the email address. This is not suppose to happen, as the name should be encoded already, but something else is going funny I guess.
What headers are the message trying to send with?
You can easily dump with this MSDN snippet:
string[] keys = message.Headers.AllKeys;
Console.WriteLine("Headers");
foreach (string s in keys)
{
Console.WriteLine("{0}:", s);
Console.WriteLine(" {0}", message.Headers[s]);
I received this error when if this is modified to "network" --- then error got resolved. ( My understanding is - Incase of specified pickupdirectory option, the header -encoding utf-8 (base64) was giving error )
Hope it helps