Registration Widget with Integrated Captcha Spam Protection in Sitefinity CMS

December 03, 2013 Digital Experience, Sitefinity
Integrated Captcha spam protection in registration widget is widely requested from many of our clients. In the following blog post I will demonstrate how to implement a custom registration control with integrated RadCaptcha.

For this modified control we will use the default template for the Registration widget. Here is the modified template based on default one.

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CustomRegistrationWidget.ascx.cs" Inherits="SitefinityWebApp.CustomRegistrationWidget" %>
<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.Fields" Assembly="Telerik.Sitefinity" %>
<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI" Assembly="Telerik.Sitefinity" %>
<%@ Register TagPrefix="sfvalidation" Namespace="Telerik.Sitefinity.Web.UI.Validation.Definitions" Assembly="Telerik.Sitefinity" %>
<asp:ScriptManager runat="server" ID="Test" />
<fieldset class="sfregisterFormWrp">
    <asp:Panel ID="formContainer" runat="server" DefaultButton="registerButton">
        <ol class="sfregisterFieldsList">
            <sf:TextField ID="firstName" runat="server" DataFieldName="FirstName" DataItemType="Telerik.Sitefinity.Security.Model.SitefinityProfile" DisplayMode="Write" Title="<%$ Resources:Labels, FirstName %>" CssClass="sfregisterField sfregisterFirstName" WrapperTag="li" />
            <sf:TextField ID="lastName" runat="server" DataFieldName="LastName" DataItemType="Telerik.Sitefinity.Security.Model.SitefinityProfile" DisplayMode="Write" Title="<%$ Resources:Labels, LastName %>" CssClass="sfregisterField sfregisterLastName" WrapperTag="li" />
            <sf:TextField ID="email" runat="server" DataFieldName="Email" DisplayMode="Write" Title="<%$ Resources:Labels, Email %>" CssClass="sfregisterField sfregisterEmail" WrapperTag="li">
                <ValidatorDefinition MessageCssClass="sfError" Required="true" ExpectedFormat="EmailAddress" />
            </sf:TextField>
            <sf:TextField ID="userName" runat="server" DataFieldName="UserName" DisplayMode="Write" Title="<%$ Resources:Labels, UserName %>" CssClass="sfregisterField sfregisterUserName" WrapperTag="li">
                <ValidatorDefinition MessageCssClass="sfError" Required="true" />
            </sf:TextField>
            <sf:TextField ID="password" runat="server" DisplayMode="Write" Title="<%$ Resources:Labels, Password %>" IsPasswordMode="true" CssClass="sfregisterField sfregisterPassword" WrapperTag="li">
                <ValidatorDefinition MessageCssClass="sfError" Required="true" />
            </sf:TextField>
            <sf:TextField ID="reTypePassword" runat="server" DisplayMode="Write" Title="<%$ Resources:UserProfilesResources, ReTypePassword %>" IsPasswordMode="true" CssClass="sfregisterField sfregisterConfirmPassword" WrapperTag="li">
                <ValidatorDefinition MessageCssClass="sfError">
                    <ComparingValidatorDefinitions>
                        <sfvalidation:ComparingValidatorDefinition ControlToCompare="password"
                            Operator="Equal" ValidationViolationMessage="<%$ Resources:ErrorMessages, CreateUserWizardDefaultConfirmPasswordCompareErrorMessage %>" />
                    </ComparingValidatorDefinitions>
                </ValidatorDefinition>
            </sf:TextField>
            <telerik:RadCaptcha Skin="Office2007" AccessKey="A" ID="RadCaptcha1" runat="server"
                ErrorMessage="You have entered an invalid code" ValidationGroup="SubmitGroup"
                ForeColor="Red" CaptchaImage-EnableCaptchaAudio="true">
            </telerik:RadCaptcha>
 
        </ol>
        <asp:Panel ID="errorsPanel" runat="server" CssClass="sfErrorSummary" Visible="false" />
        <div class="sfregisterLnkWrp">
            <asp:Button runat="server" ID="registerButton" Text="<%$ Resources:UserProfilesResources, Register %>" CssClass="sfregisterSaveLnk" />
        </div>
    </asp:Panel>
    <sf:SitefinityLabel ID="successMessageLabel" runat="server" WrapperTagName="div" CssClass="sfSuccess" />
    <asp:Panel ID="configurationErrorsPanel" runat="server" CssClass="sfErrorSummary" Visible="false">
        <div runat="server" id="smtpSettingsErrorWrapper" visible="false">
            <asp:Label runat="server" ID="smtpConfigurationErrorTitle" Text="<%$ Resources:ErrorMessages, CannotSendEmails %>" />
            <asp:Label runat="server" ID="smtpConfigurationError"></asp:Label>
        </div>
    </asp:Panel>
 
</fieldset>

The code behind is the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Telerik.Sitefinity.Web.UI.PublicControls.BrowseAndEdit;
using Telerik.Web.UI;
 
namespace SitefinityWebApp
{
    public partial class CustomRegistrationWidget : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
 
        }
 
        protected void RadCaptcha1_CaptchaValidate(object sender, CaptchaValidateEventArgs e)
        {
 
        }
    }
}

Now we have to implement the Captcha validation. We have to add a new class in our project, which should inherit the RegistrationForm class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI.WebControls;
using Telerik.Sitefinity.Security.Web.UI;
using Telerik.Web.UI;
 
 
namespace SitefinityWebApp
{
    public class Captcha : RegistrationForm
    {
        protected virtual RadCaptcha RadCaptchaControl
        {
            get
            {
                return this.Container.GetControl<RadCaptcha>("RadCaptcha1", true);
            }
        }
 
        protected void Page_Init(object sender, EventArgs e)
        {
            
        }
 
        protected override bool ValidateInput()
        {
            this.RadCaptchaControl.Validate();
            return base.ValidateInput() && this.RadCaptchaControl.IsValid;
        }
 
 
        public override string LayoutTemplatePath
        {
            get
            {
                return Captcha.layoutTemplatePath;
            }
        }
 
        private const string layoutTemplatePath = "~/CustomRegistrationWidget.ascx";
    }
}

In the end we have to register this custom control. The easiest way to achieve this is to use Sitefinity Thunder extension for Visual Studio.

You can download the whole sample here.

Kaloyan Savov