Case Study: Mapping fields from multiple Sitecore WFFM Forms to a common External Target

Consider the scenario where you have multiple WFFM forms in your project which were created independently on the multiple sites of your Sitecore instance. Now as per a new requirement, you are to push the data from all the forms into a third party system.

The third party system expects a fixed set of fields as user information data, but since your forms were created at different times and by different content authors, the availability and name of the fields are not consistent (Last Name vs Surname / Zip code vs Postal code etc). So how would you go about achieving this using a single custom action?

The best way, would be to create a mapping of fields. So on the custom submit action – which is to send the form data to the external target, we would need the content authors to map the expected fields with fields available on individual forms. In this way, the form fields as such will not need an overhaul!

To give an idea of the end result here:

  1. Content author adds the new save action

2. Edit the newly added action

3. Map fields

All required fixed fields need to be mapped with corresponding fields in every form, if a certain field is not applicable for a given form, the mapping can be skipped – corresponding field will be blank in the target system.

Here’s how we go about setting this up

Create the code for the custom save action, declaring the mapped fields as public properties.

using Newtonsoft.Json;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.WFFM.Abstractions.Actions;
using Sitecore.WFFM.Actions.Base;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Net;
using System.Net.Configuration;
using System.Net.Http;
using System.Net.Mail;
using System.Text;
using System.Text.RegularExpressions;
using MySite.Forms.Models;

namespace MySite.Forms.SaveActions
{
    public class MySiteSaveFormData : WffmSaveAction
    {
        public string EmailAddress { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Country { get; set; }
        public string CompanyName { get; set; }
        public string Title { get; set; }
        public string OptInOptOut { get; set; }
        public string Consent { get; set; }

        public string ErrorMessage { get; set; }

        public override void Execute(ID formId, AdaptedResultList adaptedFields, ActionCallContext actionCallContext = null,
            params object[] data)
        {
            Item formItem = Sitecore.Context.Database.GetItem(formId);
            string requestId = Guid.NewGuid().ToString("N");

            SaveFormDataRequest model = new SaveFormDataRequest
            {
                Email = GetValue(EmailAddress, adaptedFields),
                FormName = formItem.Fields["Title"].Value,
                FormID = formId.ToString(),
                RequestID = requestId,
                RequestedOn = DateTime.UtcNow,
                Consent = GetValue(Consent, adaptedFields) == "1",
                StandardFields = new List<FormField>
                {
                    new FormField {Key = "FirstName", Value = GetValue(FirstName, adaptedFields)},
                    new FormField {Key = "LastName", Value = GetValue(LastName, adaptedFields)},
                    new FormField {Key = "CompanyName", Value = GetValue(CompanyName, adaptedFields)},
                    new FormField {Key = "Country", Value = GetValue(Country, adaptedFields)},
                    new FormField {Key = "Title", Value = GetValue(Title, adaptedFields)},
                    new FormField {Key = "OptIn", Value = GetValue(OptInOptOut, adaptedFields)}
                },
                FormJSON = new List<FormField>()
            };

            if (!string.IsNullOrWhiteSpace(model.FormType))
            {
                foreach (AdaptedControlResult field in adaptedFields)
                {
                    model.FormJSON.Add(new FormField
                    {
                        Key = field.FieldName,
                        Value = field.Value
                    });
                }

                string json = JsonConvert.SerializeObject(model);

                /* Use the json to post form data to the third party target */
            }
        }

        private string GetValue(string formFieldId, AdaptedResultList fields)
        {
            return string.IsNullOrWhiteSpace(formFieldId) ? null :
                fields?.GetEntryByID(formFieldId) == null ? null : fields.GetValueByFieldID(formFieldId);
        }
    }
}


On Sitecore side of things, create the new custom action at /sitecore/system/Modules/Web Forms for Marketers/Settings/Actions/Save Actions using /sitecore/templates/Web Forms for Marketers/Actions/Submit Action

Point this action to the code authored above

And now, the most important bit – configure the fields mapping dialog using the following on the custom action, note that each field is represented by <public property in code>|<field name in mapping dialog>

You are all set!

Leave a Reply

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

WordPress.com Logo

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

Google photo

You are commenting using your Google 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