Sitecore Web Forms for Marketers – Custom Save Action Send Email with Attachment

Send Email with Attachment Custom Save Action

I was surprised that Web Forms for Marketers does not come with a send email with attachment Save Action by out of the box. Fortunately it can be achieved with custom code based on the existing Send Email Save Action.


I had a few requirements the client wanted me to stick to;

  1. The form would have to exist in Web Forms for Marketers so email addresses can be captured
  2. The user must receive the file from the Media Library as an attachment in the response email upon completing the Form and not a link to a file on the website
  3. Content Editors must have the ability to choose what attachment is sent per instance of the Form.


Creating a Custom Field Type in Web Form for Marketers

The Send Email Editor only allows Media Items to be linked in the Email means another approach is needed. It is possible to programmatically to create attachment from the link but brings the headache of Content Editors tagging the links they want to be attachments.

Therefore I decided to create a custom Web Forms for Marketers field that would allow the Content Editor to choose a Media Library file via the Form Designer but be hidden to end users and not surface the chosen file(s);

namespace ISlayTitans.Cms.WebForms.Fields
public class HiddenEmailAttachment : Sitecore.Form.Web.UI.Controls.List
protected override void OnInit(EventArgs e)
this.Attributes.Add("style", "display:none;");
// The chosen values can be accessed via the SelectedValue property
var mediaItemIds = SelectedValue;

By implementing the Sitecore.Form.Web.UI.Controls.List control will allow Content Editors to choose the source of the Media Items, define if one or more Media Items are to attached and then select which ones.

To add the new Web Form for Marketers Field, in the Content Editor browse to the path /sitecore/system/Modules/Web Forms for Marketers/Settings/Field Types/Custom and insert a new Item using the Field Type Template entering the Assembly name and Class name into the appropriate fields.

Web Forms for Marketers - Send Email with Attachment

Creating a Custom Save Action to Send Email with Attachment

The Save Action is based on the standard WFFM SendMessage, accessed by decompiling the appropriate dll, and adding additional steps pass the Form Fields to a new method to create the attachments and then add them to the email;

namespace ISlayTitans.Cms.WebForms.SaveActions
public class SendAttachmentEmail : SendMessage
protected override void ExecuteMail(ID formId, AdaptedResultList fields)
ProcessMessageArgs processMessageArgs = new ProcessMessageArgs(formId, fields, this.MessageType);
processMessageArgs.To.Append(this.To.Replace(";", ","));
processMessageArgs.From = this.From.Replace(";", ",");
processMessageArgs.IncludeAttachment = this.IsIncludeAttachments;
processMessageArgs.Recipient = this.Recipient;
processMessageArgs.RecipientGateway = this.RecipientGateway;
processMessageArgs.Host = this.Host;
processMessageArgs.Port = this.Port;
processMessageArgs.IsBodyHtml = this.IsBodyHtml;
processMessageArgs.EnableSsl = this.EnableSsl;
processMessageArgs.Data.Add("FromPhone", this.FromPhone ?? string.Empty);
string[] strArray1;
if (!string.IsNullOrEmpty(this.Login))
strArray1 = this.Login.Split('\\');
strArray1 = new string[1]
string[] strArray2 = strArray1;
if (strArray2.Length > 0 && !string.IsNullOrEmpty(strArray2[0]))
processMessageArgs.Credentials = strArray2.Length != 2 || string.IsNullOrEmpty(strArray2[1]) ? (ICredentialsByHost)new NetworkCredential(strArray2[0], this.Password) : (ICredentialsByHost)new NetworkCredential(strArray2[1], this.Password, strArray2[0]);
if (!string.IsNullOrEmpty(this.CC))
processMessageArgs.CC.Append(this.CC.Replace(";", ","));
if (!string.IsNullOrEmpty(this.BCC))
processMessageArgs.BCC.Append(this.BCC.Replace(";", ","));
List<Attachment> attachments = RetrieveAttachments(formId, fields);
CorePipeline.Run("processMessage", (PipelineArgs)processMessageArgs);
catch (Exception ex)
Log.Error("Failed to send email with attachment in SendAttachmentEmail WFFM save action", ex, this);
throw ex;

To retrieve the IDs of the MediaItems to be attached is done by using the FormItem, looping through its Fields to find one, or many, fields that Template is our HiddenAttachment custom Field Type and pulling out the Ids in the value property;

private List<Attachment> RetrieveAttachments(ID formId, IEnumerable<AdaptedControlResult> fields)
var attachments = new List<Attachment>();
Item item = Sitecore.Context.Database.Items[formId];
if (item != null)
var mediaItemIds = new List<string>();
var formItem = new FormItem(item);
foreach (AdaptedControlResult field in fields)
GetMediaIds(formItem, field, mediaItemIds);
GetAttachmentsFromMediaItems(mediaItemIds, attachments);
return attachments;
private static void GetMediaIds(FormItem formItem, AdaptedControlResult field, List<string> mediaItemIds)
if (formItem.Fields.Any(f => f.ID.ToString() == field.FieldID))
FieldItem fieldItem = formItem.Fields.First(f => f.ID.ToString() == field.FieldID);
if (fieldItem.Type.ID == Enumerators.SitecoreConfig.Guids.Templates.HiddenEmailAttachmentId)
var value = HttpUtility.HtmlDecode(field.Value);
var regex = new Regex(@"<item>(.*?)</item>");
var matches = regex.Matches(value);
foreach (Match match in matches)
if (!string.IsNullOrEmpty(match.Groups[1].Value))

Finally its a matter of getting the MediaItems from the list of Ids and creating attachments from its MemoryStream.

private static void GetAttachmentsFromMediaItems(List<string> mediaItemIds, List<Attachment> attachments)
foreach (string mediaItemId in mediaItemIds)
var actualAttachment = new MemoryStream();
MediaItem mediaItem = Sitecore.Context.Database.GetItem(mediaItemId);
actualAttachment.Position = 0;
var attachment = new Attachment(actualAttachment, mediaItem.Name, mediaItem.MimeType);
attachment.ContentDisposition.Size = actualAttachment.Length;
attachment.ContentDisposition.FileName = mediaItem.Name;
if (attachment != null)

And that’s it!

The approach works really well; allowing Content Editors full control of Attachments, send email with attachments on submit of a form  and its execution is scalable to allow multiple attachments from multiple fields.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s