Tuesday 4 October 2011

Sending an Email with Attachments in Sharepoint 2010

As you probably know Sharepoint provides a mechanism to send emails to users. The class that Microsoft provides for this task is called Microsoft.Sharepoint.Utilities.SPUtility and the method is called SendEmail(…).

I have to admit, this class works really well, in fact it always delivers the emails BUT there is something that it can’t do for you. Something at some point you will need, attachments. SPUtility can’t send any attachments so if at some point you want to send an appointment or file, you will not be able to do it.

What is the solution, well, because Sharepoint 2010 works under .NET 3.5 in a “ASP.NET” environment there is a nice class we can use to send attachments: System.Net.Mail.SmtpClient .

I am going to post a piece of code with a simple appointment attached to the email. I am going to do this exercise because there are plenty of examples of this class out there (files or lines of text).

I have a button in a form called CMDSendEmail, when you click it will send the email:

private void CMDSendEmail_Click(object sender, EventArgs e)
{
      string _sCalendar = null;
      _sCalendar = BuildEventCalendar( DateTime.Now, 
                                DateTime.Now,
                                DateTime.Now, 
                                "Park", 
                                "Sharepoint Discussion", 
                                "More discussion", 
                                "organaizer@email.com");
      SendSharepointEmailWithCalendarEventNetClass(
                               "from@email.com", 
                               "to@email.com",
                               "mysubject", 
                               "mybody", 
                               _sCalendar, 
                               "myevent.ics", 
                               false, 
                               true);
}
private bool SendSharepointEmailWithCalendarEventNetClass(string _sFrom, string _sTo, string _sSubject, string _sBody, string _bAttachemnt, string _sAttachmentName, bool _bIsFromLocal, bool _bDoesItHaveAttachment)
{
            bool _bResult = false;
            try
            {
                //Get the Sharepoint SMTP information from the SPAdministrationWebApplication
                string smtpServer = SPAdministrationWebApplication.Local.OutboundMailServiceInstance.Server.Address;
                string smtpFrom = _bIsFromLocal ? SPAdministrationWebApplication.Local.OutboundMailSenderAddress : _sFrom;
                //Create the mail message and supply it with from and to info
                MailMessage mailMessage = new MailMessage(smtpFrom, _sTo);
                //Set the subject and body of the message
                mailMessage.Subject = _sSubject;
                mailMessage.Body = _sBody;
                mailMessage.IsBodyHtml = true;
                if (_bDoesItHaveAttachment)
                {
                    //## Create the attachment passing the parameters
                    System.Net.Mail.Attachment _mAttachment = 
                        System.Net.Mail.Attachment.CreateAttachmentFromString(
                        _bAttachemnt,
                        _sAttachmentName,
                        System.Text.Encoding.Unicode,
                        "text/calendar");
                   
                    //##Add the attachment
                    mailMessage.Attachments.Add(_mAttachment);
                }
                //##Create the SMTP client object and send the message
                SmtpClient smtpClient = new SmtpClient(smtpServer);
                smtpClient.Send(mailMessage);
                _bResult = true;
            }
            catch (Exception ex)
            {
                _bResult = false;
            }
            return _bResult;
}
public string BuildEventCalendar(DateTime _dStart, DateTime _dEnd, DateTime _dDateStamp, string _sLocation, string _sSummary, string _sDescription, string _sOrganizer)
{
            System.Text.StringBuilder sbICSFile = new System.Text.StringBuilder();
            
            sbICSFile.AppendLine("BEGIN:VCALENDAR");
            sbICSFile.AppendLine("PRODID:-//Microsoft Corporation//Outlook 11.0 MIMEDIR//EN");
            sbICSFile.AppendLine("VERSION:2.0");
            sbICSFile.AppendLine("METHOD:PUBLISH");
            sbICSFile.AppendLine("BEGIN:VEVENT");
            sbICSFile.AppendLine("ORGANIZER:MAILTO:"+_sOrganizer);
            sbICSFile.AppendLine("DTSTART:" + _dStart.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));
            sbICSFile.AppendLine("DTEND:" + _dEnd.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));
            sbICSFile.AppendLine("LOCATION:" + _sLocation);
            sbICSFile.AppendLine("TRANSP:OPAQUE");
            sbICSFile.AppendLine("SEQUENCE:0");
            sbICSFile.AppendLine("UID:" + DateTime.Now.Ticks.ToString());
            sbICSFile.AppendLine("DTSTAMP:" + _dDateStamp.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));
            sbICSFile.AppendLine("SUMMARY:" + _sDescription);
            sbICSFile.AppendLine("PRIORITY:5");
            sbICSFile.AppendLine("X-MICROSOFT-CDO-IMPORTANCE:1");
            sbICSFile.AppendLine("CLASS:PUBLIC");
            sbICSFile.AppendLine("END:VEVENT");
            sbICSFile.AppendLine("END:VCALENDAR");
            return sbICSFile.ToString();
}


As you can see it is pretty simple you create the Event and attach it as "text/calendar" type.
I have only created one attachment, but I recommend you to try more types, to see how smooth the system is.


Conclusion: Even if Sharepoint 2010 doesn’t have the functionality to send attachments on emails, the beautiful .NET 3.5 can handle that for you in an elegant way.