Pawan Singh
Jul 16, 2025
visibility 790
star star star star star
(0 votes)

Importing Form Submission Data into Optimizely Forms Using DdsPermanentStorage

Recently, we needed to import a large number of records from a third-party system into Optimizely Forms. The data was available in CSV format, and our goal was to insert this data as form submissions within the Optimizely platform.

🔍 The Challenge

During our initial analysis, we discovered that Optimizely Forms does not offer a built-in API to directly insert or update form submissions programmatically. While the method PerformDataSubmit() handles submission automatically through the UI (taking care of cookies and submission IDs), it relies on HttpContext, which we don’t have access to in a scheduled job environment—like in our one-time migration scenario.

✅ The Solution: DdsPermanentStorage

After some investigation, we found that the internal class DdsPermanentStorage can be used to directly interact with the Optimizely Forms' data store. This allowed us to insert and update form submissions programmatically without depending on the httpContext.

We utilized this class in a scheduled job and were able to import all records successfully.

🔸 Important: To ensure these submissions show up correctly in the Form Submissions view under Edit Mode, you must include the SYSTEMCOLUMN_Language field during creation.



🕒 Handling Custom Submission DateTime

While everything was working well, we noticed that the submission timestamp (Created date) was automatically generated by the system at the time of insertion. However, our source data contained historical submission timestamps, and it was important for reporting and UI display that we preserve these original dates.

To solve this, we went one step further and overridden the default behavior to allow setting a custom submission date. We achieved this by extending DdsPermanentStorage as below.

using EPiServer.Data.Dynamic;
using EPiServer.Forms.Core.Data;
using EPiServer.Forms.Core.Models;

namespace Alloy.Customization.ExtendedDdsPermanentStorage;

public class ExtendedDdsPermanentStorage : DdsPermanentStorage
{
    public const string SYSTEMCOLUMN_SubmitTime = "SYSTEMCOLUMN_SubmitTime";
    protected override void EnsureFormFieldsExistInPostData (FormIdentity formIden, ref PropertyBag postData, out IDictionary<string, Type> typesBag)
    {
        DateTime.TryParse(Convert.ToString(postData[SYSTEMCOLUMN_SubmitTime]), out DateTime submitedTime);
        base.EnsureFormFieldsExistInPostData(formIden, ref postData, out typesBag);
        if (submitedTime > DateTime.MinValue)
        {
           postData[SYSTEMCOLUMN_SubmitTime] = submitedTime;
        }
    }
}

🧩 Dependency Injection Setup

Since this custom class may need to be reused in other parts of the solution (or injected), don’t forget to register it in the DI container if you're wrapping it inside a service or using Optimizely’s built-in services.

Hope this post helps someone facing the same challenge!

Jul 16, 2025

Comments

error Please login to comment.
Latest blogs
Architecting an Enterprise-Grade Development Pipeline in Optimizely SaaS CMS

Most enterprise teams show up to Optimizely SaaS CMS with a clear roadmap for their release pipeline: DEV → QA → Stage → Prod. Four logical...

Vipin Banka | Jul 12, 2026

Bynder DAM Connector for Optimizely SaaS CMS: Improved Metadata Property Synchronization

While working with the Bynder DAM Connector for Optimizely SaaS CMS , one of the key areas I explored was how Bynder asset metadata is synchronized...

Vipin Banka | Jul 11, 2026

Optimizely DXP: Every Supported Culture, One Searchable Page

Quick one for anyone building multi-language sites on Optimizely DXP. I put together a reference tool listing all 806 supported cultures. More...

Adnan Zameer | Jul 10, 2026 |

A day in the life of an Optimizely OMVP: London Meetup 2026

On 2nd July 2026 the Optimizely London Developer Meetup returned to The Lightwell, and the running theme across the evening was less about individu...

Graham Carr | Jul 10, 2026