liam@goldfinch ~/blog · main
Back to posts · ~/blog/posts/unique-form-submissions-in-kentico-12-mvc.md

Unique form submissions in Kentico 12 MVC

Answering a DevNet question, I wrote a C# module for Kentico 12 MVC that stops duplicate form submissions, useful for event or webinar sign-ups. It hooks BizFormItemEvents.Insert.Before, finds fields named "email", queries existing submissions with BizFormItemProvider.GetItems, and cancels with an error when it spots a match. Reusable sample code included.

When adding forms to websites, there may be occasions where you might prefer to restrict form respondents from making multiple form submissions. It could be that your form represents a method of signing up for an event, registering interest in a topic or webinar, or you might simply prefer that the same email address isn't associated with multiple form submissions.

This topic popped up recently as a question on the Questions & Answers section of the Xperience DevNet portal. If you are new to developing Xperience websites, or you find you are having trouble implementing a certain feature of Xperience, then I highly recommend submitting questions on the Q&A section of DevNet. You can get really good solutions and detailed explanations from the Xperience community, including answers from Xperience MVPs and members of the Kentico Support team.

The solution

For this question in particular, I provided sample code which can be used in your Xperience MVC site. This module intercepts a form submission, checks for fields containing the keyword email, and compares the values submitted against values from other submissions to find a match.  If it finds a match then the form submission is cancelled and an error is displayed, otherwise the form continues to process as you would expect.  You can find the sample code below:

using CMS;
using CMS.DataEngine;
using CMS.OnlineForms;
using DancingGoat.GlobalEvents;
using System.Linq;

[assembly: RegisterModule(typeof(FormGlobalEventsModule))]
namespace DancingGoat.GlobalEvents
{
    public class FormGlobalEventsModule : Module
    {
        public FormGlobalEventsModule() : base("DancingGoat.FormGlobalEventsModule")
        {
        }

        protected override void OnInit()
        {
            base.OnInit();

            // Register custom events
            BizFormItemEvents.Insert.Before += Insert_Before;
        }

        private void Insert_Before(object sender, BizFormItemEventArgs e)
        {
            var item = e.Item;

            // Sanity check to ensure we actually have a bizform item.
            if (item == null)
            {
                return;
            }

            // Get all column names that contain email.
            var columnNames = item.ColumnNames.Where(x => x.ToLowerInvariant().Contains("email"));

            // Loop over all column names containing the keyword email.
            foreach (var columnName in columnNames)
            {
                // Get the submitted email address value.
                var email = item.GetStringValue(columnName, string.Empty);

                // Lookup the current bizform for submissions with the same field value.
                var existingEntry = BizFormItemProvider.GetItems(e.Item.BizFormClassName)
                    .Column(columnName)
                    .TopN(1)
                    .WhereEquals(columnName, email)
                    .FirstOrDefault();

                // If it already exists, cancel it (displays an error on the MVC site).
                if (existingEntry != null)
                {
                    e.Cancel();
                }
            }
        }
    }
}
// related

Keep reading

umbraco-automate-developer-automation-or-marketing-automation.md 6 min
#post

Umbraco Automate: Developer Automation or Marketing Automation?

Umbraco Automate is pitched at marketing teams, but it's developer tooling, and that's fine. What would have to change, from someone who's watched Kentico do it.

#Umbraco #Open source #.NET
right-sizing-rag-ai-answers-on-my-kentico-site.md 7 min
#post

Right-sizing RAG: AI answers on my Kentico site, no vector database

You probably don't need a vector database for AI Q&A on a small site - here's the right-sized RAG behind my Kentico "Ask" button.

#Kentico #AI tooling #.NET
kentico-management-mcp-server-ai-that-builds-inside-your-cms.md 7 min
#post

Kentico's Management MCP server: AI that builds inside your CMS, and keeps every change reviewable

How I built four brand sites through Xperience by Kentico's Management MCP server — and why reviewability, not speed, is what really matters.

#Kentico #AI tooling #.NET
how-ai-changed-the-shape-of-delivery-on-a-real-kentico-project.md 6 min
#post

How AI Changed the Shape of Delivery on a Real Kentico Project

A real‑world case study exploring how AI‑assisted workflows changed decision‑making, reduced uncertainty, and accelerated delivery during an Xperience by Kentico rebuild.

#Kentico #AI tooling