Friday, March 22, 2013

Send embedded images via email to Outlook from SharePoint web part or Workflow

Recently I was working on a custom application and we had a requirement to send an email through SharePoint code with embedded images. Usually it is good practice to use SPUtility.SendEmail(...) for sending emails dynamically through code since we do not have to worry about the extracting SMTP Server information. SPUtility figures it out automatically for that server where code is running and sends these emails. But I did not find a way to embed images while sending email using SPUtility.

After spending some time I thought to use back the old fashion of .Net namespaces for sending these emails with embedded images.

1. How to embed one image in an Email and send an HTML formatted email to Outlook

Code:

 private void SendEmail( string SubjectLine, string fromaddress, string  toaddress)
        {
           
                 string strMailContent = "Send email with an image;
                string strSmtpServer = SPAdministrationWebApplication.Local.OutboundMailServiceInstance.Server.Address;

                string fromAddress = fromaddress;
                string toAddress = toaddress;
           

                string templatePath = SPUtility.GetGenericSetupPath("TEMPLATE");
                string path = templatePath + "\\LAYOUTS\\featurefoldername\\image1.gif";
         

                MailMessage mailMessage = new MailMessage(fromAddress, toAddress);
                mailMessage.Subject = SubjectLine;

                     LinkedResource logo = new LinkedResource(path);
                      logo.ContentId = "logo";
     // done HTML formatting in the next line to display my logo
            AlternateView av1 = AlternateView.CreateAlternateViewFromString("<html><body><img src=cid:logo/><br></body></html>" + strMailContent, null, MediaTypeNames.Text.Html);
            av1.LinkedResources.Add(logo);
           

                mailMessage.AlternateViews.Add(av1);
                mailMessage.IsBodyHtml = true;
                SmtpClient mailSender = new SmtpClient(strSmtpServer);
                mailSender.Send(mailMessage);
            }
        }


2. For embedding multiple images

 private void SendEmail(string SubjectLine, string fromaddress, string  toaddress)
        {
           
                 string strMailContent = "Send email with an image;
                string strSmtpServer = SPAdministrationWebApplication.Local.OutboundMailServiceInstance.Server.Address;

                string fromAddress = fromaddress;
                string toAddress = toaddress;
           

                string templatePath = SPUtility.GetGenericSetupPath("TEMPLATE");
                string logopath1 = templatePath + "\\LAYOUTS\\Featurefoldername\\logo1.gif";
                string logopath2 = templatePath + "\\LAYOUTS\\Featurefoldername\\logo2.gif";
                string logopath3 = templatePath +"\\LAYOUTS\\Featurefoldername\\logo3.gif";

                MailMessage mailMessage = new MailMessage(fromAddress, toAddress);
                mailMessage.Subject = SubjectLine;

                List<LinkedResource> resources = new List<LinkedResource>();
                LinkedResource logo1= new LinkedResource(logopath1);
                logo1.ContentId = "logo1";
                resources.Add(logo1);

                LinkedResource logo2= new LinkedResource(logopath2 );
                logo2.ContentId = "logo2";
                resources.Add(logo2);

                LinkedResource logo3= new LinkedResource(logopath3);
                logo3.ContentId = "logo3";
                resources.Add(logo3);

             

                // done HTML formatting in the next line to display my logo
                AlternateView av1 = AlternateView.CreateAlternateViewFromString("<html><body><img src=cid:logo1/><br><img src=cid:logo2/><br><img src=cid:logo3/><br></body></html>" + strMailContent, null, MediaTypeNames.Text.Html);

           
                resources.ForEach(x => av1.LinkedResources.Add(x));
                mailMessage.AlternateViews.Add(av1);
                mailMessage.IsBodyHtml = true;
                SmtpClient mailSender = new SmtpClient(strSmtpServer);
                mailSender.Send(mailMessage);

            }

        }

Wednesday, February 23, 2011

Points to note while doing Field and List level Validation

Formulas
  1. You can only compare column values to one another in a list level validation.
  2. A validation formula at the column level cannot include any other columns besides itself.  For example, [Column1]>[Column2] is an invalid formula and SharePoint will not allow it to be used at the column level.  In this case, you want to use list-level validation.
  3. There is only one formula available at the list level. 
  4. The formula syntax is similar to that used in Calculated Columns
There are a few dozen functions available - I have not tried every one.  One interesting thing to note is that SharePoint 2010 would not allow me to use the TODAY function, even when validating a Date field.  [DateColumn]>TODAY is not a valid validation formula.

Conflicts
  1. What if you have both column level validation and list level validation?
    1. The column level formulas will be evaluated first, then the list formulas
  1. What if the column and list level validations are in conflict?
    1. Example - at the list level, you require that [Text1] = [Text2], but each column has it's own validation; [Text1]="AAA", and [Text2]="BBB".  In this case, it will be impossible to actually submit a list item.  The column validations are evaluated first, but if the values validate here, they will of course fail the list validation.
  1. What if the list level validation includes columns not included in a particular content type?
    1. If a column used in the list formula isn't available in the current content type, validation will always fail.  This means that if you have multiple content types in your list,  you should not validate at the list level for a column that is not included in all content types on the list.  These columns can only be validated at the column level.

Site Columns
  1. You can set validation on custom columns of the field types listed above
  2. You can override the validation of a site column at the list level

Friday, February 4, 2011

InfoPath forms getting information from Active Directory

I had a request where I had to develop an InfoPath form for a project and user wanted a people picker in that form. In SharePoint lists/libraries we can use a "Person and Group" column which gets info from AD and will display all names but to have the same functionality in InfoPath we have to follow few manual steps BUT the good news is this do not need any programming.

2007 ships with a control called Contact Selector Control that will resolve this issue!