tags:

views:

3323

answers:

6

Hi,

I need to send email via my C# app.

I come from a VB 6 background and had a lot of bad experiences with the MAPI control. First of all, MAPI did not support HTML emails and second, all the emails were sent to my default mail outbox. So I still needed to click on send receive.

If I needed to send bulk html bodied emails (100 - 200), what would be the best way to do this in C#?

Thanks in advance.

+2  A: 

The .NET framework has some built-in classes which allows you to send e-mail via your app.

You should take a look in the System.Net.Mail namespace, where you'll find the MailMessage and SmtpClient classes. You can set the BodyFormat of the MailMessage class to MailFormat.Html.

It could also be helpfull if you make use of the AlternateViews property of the MailMessage class, so that you can provide a plain-text version of your mail, so that it can be read by clients that do not support HTML.

http://msdn.microsoft.com/en-us/library/system.net.mail.mailmessage.alternateviews.aspx

Frederik Gheysels
Beat me to it :)
Rowland Shaw
:) how is the order of answers defined ? A while ago splattne's answer was the 3rd one, now it's the first one ...Think I should read the FAQ ;) (first time around here)
Frederik Gheysels
First the accepted answer, below that all others ranked by votes
edosoft
nice to downgrade without a reason ...
Frederik Gheysels
+19  A: 

You could use the System.Net.Mail.MailMessage class of the .NET framework.

You can find the MSDN documentation here.

Here is a simple example (code snippet):

using System.Net;
using System.Net.Mail;
using System.Net.Mime;

...
try
{

   SmtpClient mySmtpClient = new SmtpClient("my.smtp.exampleserver.net");

    // set smtp-client with basicAuthentication
    mySmtpClient.UseDefaultCredentials = false;
   System.Net.NetworkCredential basicAuthenticationInfo = new
      System.Net.NetworkCredential("username", "password");
   mySmtpClient.Credentials = basicAuthenticationInfo;

   // add from,to mailaddresses
   MailAddress from = new MailAddress("[email protected]", "TestFromName");
   MailAddress to = new MailAddress("[email protected]", "TestToName");
   MailMessage myMail = new System.Net.Mail.MailMessage(from, to);

   // add ReplyTo
   MailAddress replyto = new MailAddress("[email protected]");
   myMail.ReplyTo = replyto;

   // set subject and encoding
   myMail.Subject = "Test message";
   myMail.SubjectEncoding = System.Text.Encoding.UTF8;

   // set body-message and encoding
   myMail.Body = "<b>Test Mail</b><br>using <b>HTML</b>.";
   myMail.BodyEncoding = System.Text.Encoding.UTF8;
   // text or html
   myMail.IsBodyHtml = true;

   mySmtpClient.Send(myMail);
}

catch (SmtpException ex)
{
  throw new ApplicationException
    ("SmtpException has occured: " + ex.Message);
}
catch (Exception ex)
{
   throw ex;
}
splattne
What alternatives are there to embedding passwords directly into the code?
Gabe
The NetworkCredential class is overloaded. If you provide an empty constructor, it will create the instance with the current user. Alternatively, you could also encrypt the username and password and store it externally. It also depends on how you set up your mail server. You can set up an SMTP server on the localhost and allow it to be a relay for the loopback address, so that you can send email without credentials. We do the latter. It is lightweight, simple, and requires no storing of passwords (since anyone can relay from the loopback address - meaning IIS can, as well).
joseph.ferris
You can also configure all that with `<system.net><mailSettings>` in your config file. I use this all the time to send mail to a directory while developing, then switch it to send for real when ready to go live.
dotjoe
A: 

Use the namespace System.Net.Mail. Here is a link to the MSDN page

You can send emails using SmtpClient class.

I paraphrased the code sample, so checkout MSDNfor details.

MailMessage message = new MailMessage(
   "[email protected]",
   "[email protected]",
   "Subject goes here",
   "Body goes here");

SmtpClient client = new SmtpClient(server);
client.Send(message);

The best way to send many emails would be to put something like this in forloop and send away!

bentford
Don't forget "message.IsBodyHtml = true" before sending.
GeekyMonkey
+1  A: 

Code:

using System.Net.Mail

new SmtpClient("smtp.server.com", 25).send("[email protected]", 
                                           "[email protected]", 
                                           "subject", 
                                           "body");

Mass Emails:

SMTP servers usually have a limit on the number of connection hat can handle at once, if you try to send hundreds of emails you application may appear unresponsive.

Solutions:

  • If you are building a WinForm then use a BackgroundWorker to process the queue.
  • If you are using IIS SMTP server or a SMTP server that has an outbox folder then you can use SmtpClient().PickupDirectoryLocation = "c:/smtp/outboxFolder"; This will keep your system responsive.
  • If you are not using a local SMTP server than you could build a system service to use Filewatcher to monitor a forlder than will then process any emails you drop in there.
rizzle
+1  A: 

I can strongly recommend the aspNetEmail library: http://www.aspnetemail.com/

The System.Net.Mail will get you somewhere if your needs are only basic, but if you run into trouble, please check out aspNetEmail. It has saved me a bunch of time, and I know of other develoeprs who also swear by it!

JMs
A: 

The best way to send bulk emails for more faster way is to use threads.I have written this console application for sending bulk emails.I have seperated the bulk email ID into two batches by creating two thread pools.

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net.Mail;

namespace ConsoleApplication1
{
public class SendMail 
{
    string[] NameArray = new string[10] { "Recipient 1", 
                                          "Recipient 2",
                                          "Recipient 3",
                                          "Recipient 4", 
                                          "Recipient 5", 
                                          "Recipient 6", 
                                          "Recipient 7", 
                                          "Recipient 8",
                                          "Recipient 9",
                                          "Recipient 10"
                                        };        

    public SendMail(int i, ManualResetEvent doneEvent)
    {
        Console.WriteLine("Started sending mail process for {0} - ", NameArray[i].ToString() + " at " + System.DateTime.Now.ToString());
        Console.WriteLine("");
        SmtpClient mailClient = new SmtpClient();
        mailClient.Host = Your host name;
        mailClient.UseDefaultCredentials = true;
        mailClient.Port = Your mail server port number; // try with default port no.25

        MailMessage mailMessage = new MailMessage(FromAddress,ToAddress);//replace the address value
        mailMessage.Subject = "Testing Bulk mail application";
        mailMessage.Body = NameArray[i].ToString();
        mailMessage.IsBodyHtml = true;
        mailClient.Send(mailMessage);
        Console.WriteLine("Mail Sent succesfully for {0} - ",NameArray[i].ToString() + " at " + System.DateTime.Now.ToString());
        Console.WriteLine("");

        _doneEvent = doneEvent;
    }

    public void ThreadPoolCallback(Object threadContext)
    {
        int threadIndex = (int)threadContext;
        Console.WriteLine("Thread process completed for {0} ...",threadIndex.ToString() + "at" +  System.DateTime.Now.ToString());
        _doneEvent.Set();
    }      

    private ManualResetEvent _doneEvent;
}


public class Program
{
    static int TotalMailCount, Mailcount, AddCount, Counter, i, AssignI;  
    static void Main(string[] args)
    {
        TotalMailCount = 10;
        Mailcount = TotalMailCount / 2;
        AddCount = Mailcount;
        InitiateThreads();                     

        Thread.Sleep(100000);
    }

   static void InitiateThreads()
   {
        //One event is used for sending mails for each person email id as batch
       ManualResetEvent[] doneEvents = new ManualResetEvent[Mailcount];

        // Configure and launch threads using ThreadPool:
        Console.WriteLine("Launching thread Pool tasks...");

        for (i = AssignI; i < Mailcount; i++)            
        {
            doneEvents[i] = new ManualResetEvent(false);
            SendMail SRM_mail = new SendMail(i, doneEvents[i]);
            ThreadPool.QueueUserWorkItem(SRM_mail.ThreadPoolCallback, i);
        }

        Thread.Sleep(10000);

        // Wait for all threads in pool to calculation...
        //try
        //{
        // //   WaitHandle.WaitAll(doneEvents);
        //}
        //catch(Exception e)
        //{
        //    Console.WriteLine(e.ToString());   
        //}

        Console.WriteLine("All mails are sent in this thread pool.");
        Counter = Counter+1;
        Console.WriteLine("Please wait while we check for the next thread pool queue");
        Thread.Sleep(5000);
        CheckBatchMailProcess();            
    }

    static  void CheckBatchMailProcess()
    {

        if (Counter < 2)
        {
            Mailcount = Mailcount + AddCount;
            AssignI = Mailcount - AddCount;
            Console.WriteLine("Starting the Next thread Pool");

            Thread.Sleep(5000);
            InitiateThreads();
        }

        else
        {
            Console.WriteLine("No thread pools to start - exiting the batch mail application");
            Thread.Sleep(1000);
            Environment.Exit(0);
        }
    }
}   

}

I have defined 10 recepients in the array list for a sample.It will create two batches of emails to create two thread pools to send mails.You can pick the details from your database also.

You can use this code by copying and pasting it in a console application.(Replacing the program.cs file).Then the application is ready to use.

I hope this helps you :).

Vijaya Priya