Custom submit action code sample - Without Sitecore Analytics

This is a basic Sitecore Experience Form Save Action that can be extended so it better meets your business requirements (usually around record validation and duplicate prevention in Salesforce).

using Sitecore.ExperienceForms.Models;
using Sitecore.ExperienceForms.Processing.Actions;
using System;
using System.Collections.Generic;
using System.Linq;
using Sitecore.ExperienceForms.Processing;
using FuseIT.Sitecore.Salesforce;
using Sitecore.ExperienceForms.Mvc.Models.Fields;
using FuseIT.Sitecore.SalesforceConnector.Entities;
using FuseIT.Sitecore.SalesforceConnector.Services;
using System.Globalization;
using Sitecore.Mvc.Extensions;
using FuseIT.Sitecore.SalesforceConnector;
using FuseIT.S4S.WebToSalesforce.Connection;

namespace FuseIT.Sitecore.Demo
{
    /// <summary>
    /// Sitecore Experience Forms custom submit action that will push web form input data into Salesforce using S4S connector.
    /// </summary>
    public class SubmitToSalesforceContacts : SubmitActionBase<string>
    {
        /// <summary>
        /// Get the saved Salesforce Session needed to connect to Salesforce using the Salesforce connection string name
        /// </summary>
        public SalesforceSession GetSalesforceSession
        {
            get
            {
                //Get SF session
                return SalesforceSessionCache.GetSalesforceSession("S4SConnString");
            }
        }

        public SubmitToSalesforceContacts(ISubmitActionData submitActionData) : base(submitActionData)
        {
        }

        /// <summary>
        /// Tries to convert the specified <paramref name="value" /> to an instance of the specified target type.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="target">The target object.</param>
        /// <returns>
        /// true if <paramref name="value" /> was converted successfully; otherwise, false.
        /// </returns>
        protected override bool TryParse(string value, out string target)
        {
            target = string.Empty;
            return true;
        }

        /// <summary>
        /// Submit method to extract form fields and insert/update Salesforce contact
        /// </summary>
        /// <param name="data"></param>
        /// <param name="formSubmitContext"></param>
        /// <returns></returns>
        protected override bool Execute(string data, FormSubmitContext formSubmitContext)
        {
            try
            {                
                //Get value from the form field "Email"
                var emailFieldValue = string.Empty;
                var emailField = formSubmitContext.Fields.Where(x => ((TitleFieldViewModel)x).Title.Equals("Email")).FirstOrDefault();
                if (emailField != null)
                {
                    var emailProperty = emailField.GetType().GetProperty("Value");
                    var postedEmail = emailProperty.GetValue(emailField);
                    emailFieldValue = postedEmail.ToStringOrEmpty();
                }
                
                if (string.IsNullOrEmpty(emailFieldValue))
                {
                    throw new ArgumentException("Email address cannot be null or empty.");
                }

                ContactService contactService = new ContactService(this.GetSalesforceSession);
                Contact contact = null;

                //Try to find existing Salesforce Contact from Email
                if (!string.IsNullOrEmpty(emailFieldValue) && GetContact(contactService, emailFieldValue, "Email", out contact))
                {
                    Logging.DebugFormat(this, "Salesforce Contact found with the Email: {0}", contact.Email);
                }
                else
                {
                    Logging.Debug(this, "No existing Salesforce Contact found using Email. Creating new Contact. ");
                    contact = new Contact();
                }

                contact.InternalFields["Email"] = emailFieldValue;

                //Get "FirstName" field value from the form and set it to Salesforce 
                var firstnameField = formSubmitContext.Fields.Where(x => ((TitleFieldViewModel)x).Title.Equals("FirstName")).FirstOrDefault();
                if (firstnameField != null)
                {
                    var firstNameProperty = firstnameField.GetType().GetProperty("Value");
                    var postedFirstName = firstNameProperty.GetValue(firstnameField);
                    var firstNameFieldValue = postedFirstName.ToStringOrEmpty();

                    contact.InternalFields["FirstName"] = firstNameFieldValue;
                }

                //Get "LastName" field value from the form and set it to Salesforce 
                var lastNameField = formSubmitContext.Fields.Where(x => ((TitleFieldViewModel)x).Title.Equals("LastName")).FirstOrDefault();
                if (lastNameField != null)
                {
                    var lastNameProperty = lastNameField.GetType().GetProperty("Value");
                    var postedLastName = lastNameProperty.GetValue(lastNameField);
                    var lastNameFieldValue = postedLastName.ToStringOrEmpty();

                    contact.InternalFields["LastName"] = lastNameFieldValue;
                }

                //Get "Birthdate" field value from the form and set it to Salesforce
                var birthdateField = formSubmitContext.Fields.Where(x => ((TitleFieldViewModel)x).Title.Equals("Birthdate")).FirstOrDefault();
                if (birthdateField != null)
                {
                    var birthdateProperty = birthdateField.GetType().GetProperty("Value");
                    var postedBirthdate = birthdateProperty.GetValue(birthdateField);
                    var birthdateFieldValue = postedBirthdate.ToStringOrEmpty();

                    DateTime dtValue;

                    if (!DateTime.TryParseExact(birthdateFieldValue, "M/d/yyyy hh:mm:ss tt", CultureInfo.CurrentCulture, DateTimeStyles.None, out dtValue))
                    {
                        Logging.DebugFormat(this, "Error occuren when converting Sitecore Experiance form datetime field value to to Salesforce datetime format");
                    }
                    else
                    {
                        contact.InternalFields.SetField("Birthdate", dtValue, typeof(DateTime));
                    }
                }

                contactService.SaveContact(contact);
                return true;
            }
            catch (Exception ex)
            {
                Logging.Error(this, "Error saving web form data to Salesforce contact", ex);
                return false;
            }
        }

        /// <summary>
        /// Get Salesforce contact by field
        /// </summary>
        /// <param name="contactService"></param>
        /// <param name="value"></param>
        /// <param name="field"></param>
        /// <param name="contact"></param>
        /// <returns></returns>
        private bool GetContact(ContactService contactService, string value, string field, out Contact contact)
        {
            List<Contact> contacts = contactService.GetByFieldEquals(field, value);

            if (contacts != null && contacts.Count > 0)
            {
                contact = contacts[0];
                return (contact != null);
            }

            contact = null;
            return false;
        }       
    }
}

Next Step

Error Handling

Steps