Announcements

This blog is where you'll get all the general public announcements from. Site information as well as new projects and releases will be announced here.

Invisible CAPTCHA added! Anonymous comments enabled!

I've been wanting to enable anonymous comments for quite some time, but I hadn't due to the enormous amount of BLOG spam that is being generated on the Internet.  I had considered using a CAPTCHA scheme with images, but it usually turns out to be more of a nuisance to users and requires quite a bit of coding for each and every page that uses it.  I was going to bite the bullet and use images when Dave Burke directed me to a post of his, Spam and BlogEngine.NET - Nadda, Nope, Nothin, which has a link to another post about Invisible CAPTCHA.

After doing a little research and giving up on the image approach (which requires you to turn on the IIS session state system), I started work on my favorite BLOG theme, Paperclip.  After enabling the view state, adding some server side code, and adding a single custom validator to the page, I had it working.  The only down side is that users who do not have javascript enabled in their browser will not be able to add comments.  For me, this isn't an issue as I don't support users that don't have javascript enabled.

All this being said, here is what you need to do to the post.aspx page of each and every BLOG theme to get this working:

  1. Make sure that EnableViewState="True" is in the @Page directive at the top of the page.
  2. Replace the following server side script:
    void Page_Load(object sender, EventArgs e)
    {
        if (CurrentWeblogPost != null)
            SetTitle(CurrentWeblogPost.Subject, false);
    }

    with:
    void Page_Load(object sender, EventArgs e)
    {
        if (CurrentWeblogPost != null)
            SetTitle(CurrentWeblogPost.Subject, false);
    
        InititializeCaptcha();
    }
    
    /// <summary>
    /// Initializes the captcha and registers the JavaScript
    /// </summary>
    private void InititializeCaptcha()
    {
        if (ViewState["CaptchaName"] == null || ViewState["CaptchaValue"] == null)
        {
            ViewState["CaptchaName"] = Guid.NewGuid().ToString();
            ViewState["CaptchaValue"] = Guid.NewGuid().ToString();
        }
    
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        sb.AppendLine("function SetCaptcha(){");
        sb.AppendLine("var form = document.getElementById('" + Page.Form.ClientID + "');");
        sb.AppendLine("var el = document.createElement('input');");
        sb.AppendLine("el.type = 'hidden';");
        sb.AppendLine("el.name = '" + ViewState["CaptchaName"].ToString() + "';");
        sb.AppendLine("el.value = '" + ViewState["CaptchaValue"].ToString() + "';");
        sb.AppendLine("form.appendChild(el);}");
    
        Page.ClientScript.RegisterClientScriptBlock(GetType(), "captchascript", sb.ToString(), true);
        Page.ClientScript.RegisterOnSubmitStatement(GetType(), "captchayo", "SetCaptcha()");
    }
    
    /// <summary>
    /// Gets whether or not the user is human
    ///</summary>
    private bool IsCaptchaValid
    {
        get
        {
            if (ViewState["CaptchaName"] != null && ViewState["CaptchaValue"] != null)
            {
                return Request.Form[ViewState["CaptchaName"].ToString()] == ViewState["CaptchaValue"].ToString();
            }
    
            return false;
        }
    }
    
    protected void valCaptcha_ServerValidate(object source, ServerValidateEventArgs args)
    {
        args.IsValid &= IsCaptchaValid;
    }
  3. Just before the <CSBlog:WeblogPostCommentForm... element toward the end of the file, insert:
    <asp:CustomValidator ID="valCaptcha" Display="Dynamic" EnableClientScript="False" ValidateEmptyText="True" ValidationGroup="CreateCommentForm" OnServerValidate="valCaptcha_ServerValidate" runat="server"><p><strong>Automatted entry detected, comment not saved.</strong></p></asp:CustomValidator>
  4. Add the following attribute to the <CSBlog:WeblogPostCommentForm... element toward the end of the file:
    ValidationGroup="CreateCommentForm"

That's it, you're done.  If you run into any issues, please post them here.

UPDATE: I just learned about reCAPTCHA, which has an ASP.NET interface.  I might look more closely into using it at a later date.

Comments

Robbie Coleman said:

testing to see if you have CAPTCHA for your own blog. ;)

# August 10, 2008 5:12 PM

Bill Bosacker said:

Yep, I've added it to each and every blog theme.

# August 10, 2008 6:10 PM

gorge said:

thank you for this information and code

# January 3, 2009 6:00 AM

aaa said:

test

# June 7, 2009 8:35 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)