1

I've written a code to run a timer job which runs at the start of a month informing users by email to visit the site.
Here's the code of the execute method:

public override void Execute(Guid targetInstanceId)
    {
        SPWebApplication webApp = SPWebApplication.Lookup(new Uri("http://server"));
        string smtpServerName = string.Empty;
        string from = string.Empty;
        //setting the website from where the timer job will run
        SPWeb web = webApp.Sites[0].RootWeb;
        //retrieving from address from the central admin site
        from = web.Site.WebApplication.OutboundMailSenderAddress;
        //retreiving smtpservername from the central admin site
        smtpServerName = web.Site.WebApplication.OutboundMailServiceInstance.Server.Address;
        //retreiving the groups in the website
        SPGroupCollection collGroups = web.SiteGroups;
        //logic to send mail to all users in all groups
        MailMessage mailMessage = new MailMessage();
        mailMessage.From = new MailAddress(from);
        string to = string.Empty;
        foreach (SPGroup group in collGroups)
        {
            foreach (SPUser user in group.Users)
            {
                //bool flg1 = user.Email == null;
                if (user.Email != null)
                {
                    //mailMessage.To.Add(user.Email);                        
                    to = user.Email + ",";
                }
            }
        }
        mailMessage.Subject = "Acknowledgement Mail";
        mailMessage.To.Add(to);
        mailMessage.Body = "Sup yo";
        mailMessage.IsBodyHtml = false;
        SmtpClient client = new SmtpClient(smtpServerName);
        client.UseDefaultCredentials = true;
        client.Port = 25;
        client.EnableSsl = false;
        client.DeliveryMethod = SmtpDeliveryMethod.Network;
        try
        {
            client.Send(mailMessage);
        }
        catch (SmtpException)
        {
            return;
        }
        catch (ArgumentNullException)
        {
            return;
        }
    }


Now just for testing purposes I ran this timer job every 5 minutes in an hour. Now, suppose there are 2 users in a group with email addresses a@abc and b@abc. I want the email to be sent with the "To" address being a@abc; b@abc; and I'm using smtp4dev for delivering the messages. What I saw was that the timer job had run twice in the 5 minutes and had sent 3 messages with the 1st being to a, then the 2nd being to a and b and the third being to a,b and again a. How do I make it run only once with only one message being sent regardless of the duration and only a;b in the "To" address?

EDIT: I forgot to restart my timer service after making changes in the code. It works now but the timer job runs multiple times within the scheduled interval instead of just once. Any suggestions for that? Sorry for messing this up!

Akhoy
  • 502
  • 1
  • 13
  • 24

2 Answers2

0

This is because you are using mailMessage.To.Add(to); wrong. Each instance of MailAddress (MailMessage.To) can only hold a single mail address. What you need to do is to add each mail address separately (hence the .Add method).

What you will need to do is to uncomment your previously used code: //mailMessage.To.Add(user.Email);

See the following post withe exactly your problem, someone trying to use commas to separate mails.

Dennis G
  • 21,405
  • 19
  • 96
  • 133
  • Thanks for the reply! My code worked perfectly. I had just forgotten to restart my timer service after making changes. It now sends the emails correctly but when I want the timer job to run just once in the specified time interval, it is running multiple times. Can you also please tell me if a user is present in more than 1 group, how do I put only 1 instance of him in "To"? Thanks. – Akhoy Jan 03 '13 at 13:10
  • Thanks to [link1](http://stackoverflow.com/questions/9673/remove-duplicates-from-array) and [link2](http://stackoverflow.com/questions/4884050/create-comma-separated-strings-c) , I put one instance of the users. Just wanna know how to run the timer job once. Sorry again! – Akhoy Jan 03 '13 at 13:33
  • 1
    A timer job definitely executes only once in the specified time frame. So there must be something else weird going on. Try debugging it and see whether it is the timer job executing three times or your SMTP server doing some weird stuff. To debug a timer job you will need to attach to `SPTIMERV4.EXE` (restart it after deploying). – Dennis G Jan 03 '13 at 13:34
  • Nope, debugged it and can't see anything weird. Don't know why it is happening though. And, do you know how to embed links while sending mails in C#. For eg. if the user gets the email to visit the site, the link of the site should be there as well. Can you help me in doing that? Thanks. – Akhoy Jan 03 '13 at 13:59
  • You should post a new question about that and close this one. You can format your mail with HTML and embed links that way. – Dennis G Jan 03 '13 at 14:12
0

My code ran when I ensured I had the following in place:
1) I forgot to restart the timer service after making changes to the code.
2) I used link1 and link2 to filter out duplicate users existing in more than one group.
3) Since I had more than 1 web application, the code for 1 application was being used for other web applications as well hence the repeated emails.
Sorry for asking this question and hope this helps someone someday.

Community
  • 1
  • 1
Akhoy
  • 502
  • 1
  • 13
  • 24