Form
Integrations

Aug 27

Introduction

Its easy for users to create forms through Sitefinity. But the storage is a simple list and most people want some cool analytics and management of their form data such as provided by Salesforce or ActOn. In this post I look at an easy way to push our forms data to these third party services.

One of the issues with integrating a third party form is the special requirements to display it. Styling, iframe, scripts... all that stuff. Not always difficult but not always clean. Most of these services allow you to POST form data directly to them or have some endpoint that you can use. If that's the case you can create and style forms the Sitefinity way and use the FormCreated event to capture and then push that form information to your service.

Form Created Event

Standard Sitefinity event which give you access to all that form data.

To get our form data we need to access the Controls property. If you are POSTing to an endpoint you want to map these into a NameValeCollection and send it along. Here is an example.

var content = new NameValueCollection();
    foreach (var field in eventInfo.Controls) 
    {
    content.Add(field.FieldName, field.Value.ToString()); } using (var client = new WebClient()) {      var response = client.UploadValues("https://postUrl", content);      var responseString = Encoding.Default.GetString(response); }

But the issue

The field name will need to match the name expected at your destination. For example, you may create a field name called FirstName but your target is expecting 'oid567_first_name'. The way around this is to ensure you name your form field control with the correct name to ensure it matches when you send it on. But that is done deep down in the control properties. Advanced -> Model -> MetaField -> FieldName.

And there is another issue. After you set this, you can not change it as it forms the basis of the databases column name.

Form Field

If you get it wrong or need to change it you will need to 'duplicate' or create a new control and delete the original one. Maybe not a big deal but that will also mean you lose all the data in that column from the database. Again, maybe not a big deal since you are pushing it to a third party system anyway.

But the solution

The class used by Sitefinity to hold all the Field Control properties is much richer but it is an internal class and not visible by intellisense. But during run time you will see a lot more properties. And in there is a field that allows us to set a alternate Field Name and it is right under the Advanced properties.

Form Field

 

When you run the program you can see a lot of extra properties available and the one we want is 'FieldControlName'.

Form Properties

To access it we just need to use Reflection in our code.

var content = new NameValueCollection();
foreach (var field in eventInfo.Controls)
{
    String fieldName = (String)field.GetType().GetProperty("FieldControlName").GetValue(field, null);
    String fieldValue = field.Value == null ? "" : field.Value.ToString();
 
    content.Add(fieldName, fieldValue);
}
using (var client = new WebClient())
{
    var response = client.UploadValues("https://postUrl", content);
    var responseString = Encoding.Default.GetString(response);
}

Great, we now have the ability to allow editors to create forms in their Third Party Form service and in Sitefinity and have them automatically connect without the need for a Developer.

Issue number two

You may find you need to provide certain values to your third party for types of controls. The most common is True and False, Yes and No, 1 and 0.

Also, the Sitefinity check box control isn't a real True or false field. Its an multi-selection field. If you have just one option, it is still treated as a multi selection. So it doesn't return a True False, it returns a string of values and you will need then alter it to fit a Boolean field.

Here is a solution I came up with.

var content = new NameValueCollection();
foreach (var field in eventInfo.Controls)
{
    String fieldName = (String)field.GetType().GetProperty("FieldControlName").GetValue(field, null);
    String fieldValue = field.Value == null ? "" : field.Value.ToString();
    if ((String)field.GetType().GetProperty("ControlType").GetValue(field, null) == "Checkboxes" && fieldName.StartsWith("tf"))
    {
        fieldName = fieldName.Replace("tf_", String.Empty);
        fieldValue = field.Value == null ? "False" : "True";
    }
 
    content.Add(fieldName, fieldValue);
}

First, I want to know if the control should be treated as a True or False checkbox or if it should be treated as a multi selection field. To achieve this, when creating the field I pre-fix a 'tf_' to the name. I then check for this and set it to the value I want as well as removing the prefix.

Other notes

If your third party expects an identifier or some common field(s) for your form submission you can also add these in via code rather than having the editor have to add in a bunch of hidden fields on the form.

You might want to also convert any null values to empty strings to avoid issues at the other end.

You also don't need to filter out any excess fields. At least with a HTTP Form POST. All those extra fields just get ignored.


Darrin Robertson - Sitefinity Developer

Thanks for reading and feel free to comment - Darrin Robertson

If I was really helpful and you would buy me a coffee if you could, yay! You can.


Leave a comment
Load more comments

Make a Comment

recapcha code