Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • iWuha 1 post 50 karma points
    Oct 05, 2012 @ 08:15
    iWuha
    0

    custom field type not saving

    Hi, I created a custom captch fieldtype using MSCaptcha. The custom control seems to be working fine in a normal .aspx page, but it's not working when it's within contour form page. I added a custom validator to validate the captcha text, the validation works fine but the form is not submitting even though the page is valid. I wonder if there's anything wrong my fieldtype? Any help would be appreciated. Thanks.

    Here is the code for my custom captcha control:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using MSCaptcha;

    namespace Model.Forms.Controls
    {
        public class Captcha : TextBox
        {
            public CaptchaControl CaptchaControl
            {
                get
                {
                    EnsureChildControls();
                    return this.captcha;
                }
                set
                {
                    this.captcha = value;
                }
            }

            private CaptchaControl captcha;
            private CustomValidator captchaVal;

            protected override void OnInit(EventArgs e)
            {
                string vGroup = string.Empty;
                List<RequiredFieldValidator> reqValidators = this.ControlsByTypeUsingAncestor<RequiredFieldValidator>(this.Page);

                if (reqValidators != null)
                {
                    var validatorWithGroupSet = (from v in reqValidators
                                                 where v.ValidationGroup != string.Empty
                                                 select v);

                    if (validatorWithGroupSet != null)
                        vGroup = validatorWithGroupSet.FirstOrDefault().ValidationGroup;
                }

                this.captcha = new CaptchaControl();
                this.captcha.CaptchaBackgroundNoise = CaptchaImage.backgroundNoiseLevel.Low;
                this.captcha.NoiseColor = System.Drawing.Color.FromArgb(251, 194, 196);
                this.captcha.CaptchaLength = 4;
                this.captcha.CaptchaHeight = 60;
                this.captcha.CaptchaWidth = 250;
                this.captcha.CaptchaLineNoise = CaptchaImage.lineNoiseLevel.None;
                this.captcha.CaptchaMinTimeout = 5;
                this.captcha.CaptchaMaxTimeout = 240;

                base.CssClass = "text";

                this.captchaVal = new CustomValidator();
                this.captchaVal.ErrorMessage = "Invalid code";
                this.captchaVal.ServerValidate += new ServerValidateEventHandler(captchaVal_ServerValidate);
                this.captchaVal.IsValid = true;
                this.captchaVal.Display = ValidatorDisplay.Dynamic;
                this.captchaVal.ValidateEmptyText = true;
                this.captchaVal.EnableClientScript = false;
                this.captchaVal.CssClass = "contourError";

                if (!string.IsNullOrEmpty(vGroup))
                {
                    base.ValidationGroup = vGroup;
                    this.captchaVal.ValidationGroup = vGroup;
                }

                base.Controls.Add(this.captchaVal);
                base.Controls.Add(this.captcha);
            }

            void captchaVal_ServerValidate(object source, ServerValidateEventArgs args)
            {
                try
                {
                    args.IsValid = ValidateCaptcha();
                }
                catch
                {
                    args.IsValid = false;
                }
            }

            private bool ValidateCaptcha()
            {
                bool flag = true;

                if (this.captcha != null)
                {
                    if (string.IsNullOrEmpty(base.Text))
                    {
                        flag = false;
                    }
                    else
                    {
                        this.captcha.ValidateCaptcha(base.Text);
                        flag = this.captcha.UserValidated;
                    }
                }
                else
                {
                    flag = false;
                }

                if (flag)
                    this.captchaVal.Style.Add("display", "none");
                else
                    this.captchaVal.Style.Add("display", "block");

                return flag;
            }

            protected override void Render(HtmlTextWriter writer)
            {
                base.RenderChildren(writer);
                base.Render(writer);           
            }

            /// <summary>
            /// get find control method using generics
            /// </summary>
            /// <typeparam name="T">type of item you want</typeparam>
            /// <param name="ancestor">parent to start looking from</param>
            /// <returns>collection of T items</returns>
            public List<T> ControlsByTypeUsingAncestor<T>(Control ancestor) where T : Control
            {
                var controls = new List<T>();

                //Append to search results if we match the type
                if (typeof(T).IsAssignableFrom(ancestor.GetType()))
                {
                    controls.Add((T)ancestor);
                }

                //Recurse into child controls
                foreach (Control ctrl in ancestor.Controls)
                {
                    controls.AddRange(ControlsByTypeUsingAncestor<T>(ctrl));
                }

                return controls;
            }
        }
    }

     

    And my custom field type:

    using System;
    using System.Collections.Generic;
    using System.Web.UI.WebControls;
    using Umbraco.Forms.Core;

    namespace Model.Forms.FieldTypes
    {
        public class Captcha : FieldType
        {
            public Controls.Captcha CaptchaControl;

            public List<object> Value;

            public Captcha()
            {
                base.Id = new Guid("F8C089B9-7D8F-47B0-A594-9FD9903FBF42");
                base.Name = "Captcha";
                base.Description = "Renders a Captcha";
                this.Icon = "textfield.png";
                this.DataType = FieldDataType.String;
                this.Value = new List<object>();

                this.CaptchaControl = new Controls.Captcha();
            }

            public override WebControl Editor
            {
                get
                {
                    return this.CaptchaControl;
                }
                set
                {
                    base.Editor = value;
                }
            }

            public override List<object> Values
            {
                get
                {
                    if (!string.IsNullOrEmpty(this.CaptchaControl.Text))
                    {
                        this.Value.Clear();
                        this.Value.Add(this.CaptchaControl.Text);
                    }
                    return this.Value;
                }
                set
                {
                    this.Value = value;
                }
            }

            public override bool SupportsPrevalues
            {
                get
                {
                    return false;
                }
            }

            public override bool SupportsRegex
            {
                get
                {
                    return false;
                }
            }

            public override string RenderPreview()
            {
                return "<img src=\"/Images/layout/capex.jpg\" alt=\"captcha\" /><br /><input type=\"text\" class=\"textfield\" />";
            }

            public override string RenderPreviewWithPrevalues(List<object> prevalues)
            {
                return this.RenderPreview();
            }
        }
    }

     

  • Andrew Weddle 1 post 21 karma points
    Aug 15, 2014 @ 13:37
    Andrew Weddle
    0

    Hi iWuha,

    Sorry to drag up an old thread, but I have a requirement for the same functionality as the above.  I have found the source of your problem, but not a solution.

    The problem is that the captchaVal_ServerValidate event seems to be firing twice.  The first time it validates successfully, however the second time it runs, the ValidateCaptcha() throws an exception and hence the catch returns false.

    I have implemented a workaround, but it's so hacky and I'm not proud that I'm not even going to post the code here!

    Did you ever get this working correctly?

    Andrew

Please Sign in or register to post replies

Write your reply to:

Draft