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();
Related
we send emails with attachments by the ews-service with the follwing code...
EmailMessage message = new EmailMessage(ExchangeServiceController);
EmailAddress sender = new EmailAddress
{
MailboxType = MailboxType.Mailbox,
Address = senderAdress
};
message.From = sender;
message.ToRecipients.AddRange(email.SendTo.GetEmailAdressRange());
message.Subject = email.Subject;
message.Body = new MessageBody(BodyType.HTML, emailText);
string[] fileEntries = SignatureController.GetSignatureImagesFiles();
int i = 0;
foreach (string fileName in fileEntries.Where(f => f.Contains("image")))
{
FileInfo info = new FileInfo(fileName);
message.Attachments.AddFileAttachment(info.Name, fileName);
message.Attachments[i].IsInline = true;
message.Attachments[i].ContentId = info.Name;
i++;
}
foreach (string filename in GetAttachmentsAsFilePathList())
{
message.Attachments.AddFileAttachment(filename);
}
var mailbox = new Mailbox(sender.Address);
var folderIdDrafts = new FolderId(WellKnownFolderName.Drafts, mailbox);
var folderIdSent = new FolderId(WellKnownFolderName.SentItems, mailbox);
// save email at draft to get the mime-content
message.Save(folderIdDrafts);
message.Load(new PropertySet(ItemSchema.MimeContent));
email.EmlContent = message.MimeContent;
if (template.SaveMessageOnSend)
{
message.SendAndSaveCopy(folderIdSent);
}
else
{
message.Send();
}
The email saved in draft. After this we get sometimes an follwoing error...
Type: Microsoft.Exchange.WebServices.Data.ServiceResponseException
Source: Microsoft.Exchange.WebServices
Message: The operation can't be performed because the item is out of date. Reload the item and try again.
HResult: -2146233088 (0x80131500)
InnerException: null
HashedSignature: 49E2BF981546C920B6A4BC0B27476A40
StackTrace:
bei Microsoft.Exchange.WebServices.Data.ServiceResponse.InternalThrowIfNecessary()
bei Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute()
bei Microsoft.Exchange.WebServices.Data.ExchangeService.SendItem(Item item, FolderId savedCopyDestinationFolderId)
bei Microsoft.Exchange.WebServices.Data.EmailMessage.InternalSend(FolderId parentFolderId, MessageDisposition messageDisposition)
It happens often with attachment over 6 MB.
The timeout is over 1 minute and the error becomes before this time.
The maxsize is over 10 MB
When i take this email at outlook and send it from the draft it works fine.
Have anybody an idea to solve this problem?
best regards steve
The reason you get the error is because the changekey is stale at the time you submit the message. This can happen if another client makes a modification on the message or Store level AV can do it see changekey in https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/itemid?redirectedfrom=MSDN. With the line
message.Load(new PropertySet(ItemSchema.MimeContent));
This will be forcing the Exchange Store to do an one the fly conversion of the Message to Mime. I'd would try doing another load before sending the message and just ask for the IdOnly
message.Load(new PropertySet(ItemSchema.MimeContent));
email.EmlContent = message.MimeContent;
message.Load(new PropertySet(BasePropertySet.IdOnly));
That should ensure you have the latest changekey before send, otherwise you could probably just build the MIME message with something like MailKit and send it in one operation rather then saving the draft.
I am developing an Outlook add-in using VSTO that checking spelling of the mail content while composing.
In Reply mails, How can I check only the reply content by excluding the old conversation ?
This is what I am doing now.But I need to know whether there is any proper object or method to get current reply content.
Outlook.MailItem mailItem = inspector.CurrentItem as Outlook.MailItem;
string temp = mailItem.Body;
int target= temp.IndexOf("\r\nFrom:");
string contentToCheck= temp.Substring(0, target);
There is no built in property that signifies the end of the new message and the start of a reply in body text.
What can be done is store common text that marks the end of the new message and check for that when reading the body. Things like ' FROM:', 'Regards,' 'Thanks,'...
Something similar to:
while ((line = bodytext.ReadLine()) != null)
{
foreach(string ending in MYLISTOFCOMMONENDINGS)
{
if (line.StartsWith(ending))
return sb.ToString(); //we are done
//here sb is a string builder consuming new lines
}
//read the line and check spelling
}
Look for the bookmark named "_MailOriginal". The script below inserts text just before the original message begins:
set objDoc = Application.ActiveInspector.WordEditor
If objDoc.Bookmarks.Exists("_MailOriginal") Then
' is there the original email? (_MailOriginal)
set objBkm = objDoc.Bookmarks("_MailOriginal")
Set objSel = objDoc.Application.Selection
objSel.Start = objBkm.Start-2 'give room for the line break before. It includes the line
objSel.End = objSel.Start
objSel.Text = "test"
End If
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 , ""));
}
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.
I want to create a mailing list via asp.net .I've studied a lots of article about it . but all of them were the same .in those article was written that I should use this code
var list = from c in context.Emails orderby c.EmailAddress select c.EmailAddress;
MailMessage mail = new MailMessage();
foreach (var c in list)
{
try
{
mail.From = new MailAddress(txtfrom.Text);
mail.To.Add(new MailAddress(c.ToString()));
mail.Subject = txtSub.Text;
mail.IsBodyHtml = true;
mail.Body = txtBody.Text;
if (FileUpload1.HasFile)
{
mail.Attachments.Add(new Attachment(FileUpload1.PostedFile.InputStream, FileUpload1.FileName));
}
SmtpClient smtp = new SmtpClient();
smtp.Send(mail);
}
catch (Exception)
{
}
}
so the question is that ,is this way really useful and successful to sending lots of emails? (for example 2000 emails?)
in those articles was written that i should put delay after each period times (for example after sending 50 emails).and I wanna know how to make delay between sending emails.
I'm looking for a perfessional way to create this project
I was wondering if someone gives me open source mailing list in asp.net
I'd change the code like this
var list = from c in context.Emails orderby c.EmailAddress select c.EmailAddress;
MailMessage mail = new MailMessage();
try
{
mail.From = new MailAddress(txtfrom.Text);
foreach (var c in list)
{
mail.To.Add(new MailAddress(c.ToString()));
}
mail.Subject = txtSub.Text;
mail.IsBodyHtml = true;
mail.Body = txtBody.Text;
if (FileUpload1.HasFile)
{
mail.Attachments.Add(new Attachment(FileUpload1.PostedFile.InputStream, FileUpload1.FileName));
}
SmtpClient smtp = new SmtpClient();
smtp.Send(mail);
}
catch (Exception)
{
//exception handling
}
At least, smtp.Send() is invoked only once.
Try using multiple threads, here is an example; msdn forum sendin bulk mails
Probably, you have some time limit for running you script (i.e 30 seconds). I suggest split into 2 steps:
format e-mails you need and write them into database table (with status - "not sent")
run another script/program, select N e-mails from table, send and mark them as "sent"
wait/sleep N seconds
repeat 2nd step
This lets you to send almost unlimit number of e-mails, w/o timeout
Also - pay attention if you have some limit on sending e-mails per hour/day on your hosting!
Create work items for emails to be sent and push them to queue. Then use as many competing consumers (aka workers) as you want to send those emails.
The asp app only needs to create an XML with the info and save it.
Use a windows service with a filewatcher. This service only detect the creation of the list in XML and send it.