I've recently had a similar requirement to this question. The answer above from Jesper Hoff is great if all you need to do is get the form data saved into the configured database for WFfM. However what it doesn't do is honour the Save Actions associated with the form. So it's fine if you want to record submissions into SQL Server, but it doesn't help if you need to send them in an email, or transmit them to a CRM. I needed to make email sending work in the code I was working on, so have done a bit more digging into the innards of WFfM:
If you want your code-based submission to honour the configured Save Actions for a form then you need to make three key changes to the code above:
- Firstly you need to make use of the
Sitecore.Form.Core.Submit.SubmitActionManager.Execute()
method rather than Sitecore.Forms.Data.DataManager.InsertForm()
. This appears to be what the innards of WFfM call when you post back a valid form.
- Secondly you need to fetch and configure the set of Save Actions that have been set up for your WFfM for definition. And there's a bit of juggling required to get this data in the right format.
- And thirdly you need to collect your form data as
ControlResult
objects not AdaptedControlResult
. The data you pass in gets wrapped automatically as part of the call to Execute()
.
Ignoring error checking for clarity, I ended up with code like this:
List<ControlResult> results = new List<ControlResult>();
results.Add(makeControlResult(_nameFieldID, "Name", "Bob Jones"));
results.Add(makeControlResult(_emailFieldID, "Email", "B.Jones@test.com"));
results.Add(makeControlResult(_messageFieldID, "Message", "Lorem ipsum. Dolor sit amet."));
Item formItem = Sitecore.Context.Database.GetItem(_yourFormID);
SitecoreSimpleForm simpleForm = new SitecoreSimpleForm(formItem);
var saveActionXml = simpleForm.FormItem.SaveActions;
var actionList = Sitecore.Form.Core.ContentEditor.Data.ListDefinition.Parse(saveActionXml);
List<ActionDefinition> actionDefinitions = new List<ActionDefinition>();
actionDefinitions.AddRange(actionList.Groups.SelectMany(x => x.ListItems).Select(li => new ActionDefinition(li.ItemID, li.Parameters) { UniqueKey = li.Unicid }));
Sitecore.Form.Core.Submit.SubmitActionManager.Execute(_formID, results.ToArray(), actionDefinitions.ToArray());
The set of save actions and their configuration is saved in the Item
for your form, but you have to wrap the item in a SitecoreSimpleForm
object to get it out. What you get back is XML, so you then need to parse it with the Sitecore.Form.Core.ContentEditor.Data.ListDefinition.Parse()
method in order to get back a set of deserialised Save Action objects. However, they're not the right sort of objects for the SubmitActionManager
so you need to project them into ActionDefinition
objects in order to make use of them.
(Note that the Save Action objects you get after parsing the XML aren't in a flat list, so you need to use something like SelectMany()
to flatten it before using them)
The makeControlResult()
method referenced above is just to make the snippet clearer. It just creates a ControlResult
object from the data about a form field:
public ControlResult makeControlResult(string fieldID, string fieldName, string fieldValue)
{
return new ControlResult(fieldName, fieldValue, string.Empty)
{
FieldID = fieldID,
FieldName = fieldName,
Value = fieldValue,
Parameters = string.Empty
};
}
Depending on how you're getting hold of your data, you may prefer to use a variation on the method in the other answer to generate this data.
I also wrote up a bit more detail of how I arrived at this answer on my blog. That post also includes a snippet about how to get back any errors that the Save Actions might generate - which can be important when you're using multiple Save Actions.