I need to call Tracker.Current.Session.Identify(emailAddress) on my Contact in a save action in a WFFM form. However the onSave action is triggered on the CM, where Tracker.Current is null.

Is there a pipeline where I could do this on the CD?

4 Answers 4


To make the save action run on CD, check the Client Action box on the Save Action. enter image description here

  • Yep, didn't know about the existence of that tiny checkbox :) Oct 15, 2016 at 6:54

I've done this through a custom Save Action for WFFM, not through a pipeline.

NOTE: The following code is for 8.0, not 8.1. 8.1 changed the method signature for Execute. You can read more at https://citizensitecore.com/2016/02/03/changes-to-wffm-save-actions-in-sitecore-8-1/.

I created a save action called IdentifyXdbContact, implementing ISaveAction from the Sitecore.Form.Submit namespace in Sitecore.Forms.Core.dll.

namespace MyAssembly.Wffm.Actions
    public class IdentifyXdbContact : ISaveAction
      public string FirstNameFormFieldName { get; set; }
      public string LastNameFormFieldName { get; set; }
      public string EmailFormFieldName { get; set; }

      public void Execute(ID formid, AdaptedResultList fields, params object[] data)
          if (Tracker.Current != null && Tracker.Current.Contact.Identifiers.IdentificationLevel != ContactIdentificationLevel.Known)
            var emailField = fields.GetEntryByName(EmailFormFieldName);
            if (emailField != null)
              var emailAddress = emailField.Value;
              if (!String.IsNullOrEmpty(emailAddress))
                  var emailFacet = Tracker.Current.Contact.GetFacet<IContactEmailAddresses>("Emails");

                  if (!emailFacet.Entries.Contains("Work Email"))
                    var email = emailFacet.Entries.Create("Work Email");
                    email.SmtpAddress = emailAddress;
                    emailFacet.Preferred = "Work Email";

                  var firstNameField = fields.GetEntryByName(FirstNameFormFieldName);
                  var lastNameField = fields.GetEntryByName(LastNameFormFieldName);
                  if (firstNameField != null || lastNameField != null)
                    var firstName = firstNameField.Value ?? String.Empty;
                    var lastName = lastNameField.Value ?? String.Empty;
                    var personalInfoFacet = Tracker.Current.Contact.GetFacet<IContactPersonalInfo>("Personal");
                    personalInfoFacet.FirstName = firstName;
                    personalInfoFacet.Surname = lastName;

Then, back in Sitecore, I created a new Submit Action in the /sitecore/system/Modules/Web Forms for Marketers/Settings/Actions/Save Actions folder with the following configuration:

Save Action Configuration

Note the Parameters field. My form has three fields on it: First Name, Last Name and Email Address. The three items listed in that field correspond as follows:

<PropertyNameInClass>Name Of Field On Form</PropertyNameInClass>

Finally, on the WFFM form itself, in the Save Actions, I simply select my new Save Action:

Add Save Action to Form

Now, when my form is submitted, the information from the form is used to identify the current session, if it's not already identified.

Since my property names and field names are hardcoded in my save action, this custom action could be improved substantially by creating a new SPEAK interface in the Save Actions dialog (available when clicking on the Edit button) allowing the user to configure which fields go to which property.

  • 1
    Also good to mention that you need to tick the 'Client...' checkbox on the Save Action item, otherwise it will be invoked on CM where it doesn't work ;-) Oct 15, 2016 at 6:52
  • I would like to add that it is probably better to inherit from WffmSaveAction class Nov 2, 2016 at 3:10

The use of the Identify() method has a very specific use case. It requires that the Page context be present which isn't the case in pipelines, events, handlers, etc.

What I've learned is that the Identify method is really only for specifically identifying a contact and setting the analytics cookie.

However, in your WFFM action, you are probably wanting to do something like add information to a contact or create the contact.

In those cases, instead of using Identify, I would utilize the ContactRepository class to load/create your contact, setting the identifier as needed, and any other custom facet information that you may have.

Then, at the end of your WFFM action, on the success page, I would include the email address (assuming that's the identifier) and perform the Identify then, instead of the action.

I'm not in a position where I can attached example code at the moment, this is a mobile answer. However, once I can, I'll whip up an example of creating the contact, setting the identifier, and then saving it.

  • Hi Pete, using the ContactRepository makes you account for situations where you've already got a contact with the same email. Identify() will take care of that by merging. The success action seems to be a good alternative, because it runs in the CD. Thanks:) Oct 15, 2016 at 6:59
  • You can create new contacts if one doesn't exist, or edit one where it does. then, once you are able.to identify, the merge will take care of that. Oct 15, 2016 at 7:18

The normal process for identifying a contact using WFFM involves the following save actions:

  • Create User (In extranet - This will be skipped if a user already exists - don't worry)
  • User Login (By Email)

Unless there is a particular reason why you need to write custom code - these will identify the contact for you.

Additionally, I'd suggest adding the Update Contact Details save action to update the xDB contact with any other information you have such as name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.