So, today, i wanted to use reCAPTCHA. Since this is an online service I was a bit skeptical at first with regard to downtime. However their faq states the following :
reCAPTCHA has distributed locations and multiple servers.
With that, we know that the service should be available pretty much all the time. And honestly, if it's good enough to service facebook's massive user base, it's good enough for me. Fact is, many people are already familiar with the service and know what to expect and how to proceed. However, the deciding factor was the noble cause of this project.
Basically for every captcha that is deciphered, you are actually helping decode a word in a book that was digitized for the public domain by volunteers using OCR(optical character reconigition). Sometimes there are a few words that an OCR cannot read and these are the words presented in the catpcha. So while fighting spam, you are actually helping digitize books. Brilliant! I was sold 

If your looking to using this captcha service, then, after signing up to the service on their site ReCAPTCHA , you shall be provided with a public/private key to access the service. And this is all you need, since they already have a custom web control that you can insert into your asp.net pages to communicate with their service and consume the captcha. You can inform yourself more about how to consume it from your webform pages here : reCAPTCHA AND ASP.NET
Now, while this is all working nicely, getting it to play nice with the UpdatePanel might be difficult for some. I say that because i have read a few articles online with workarounds, when there was no need. So the goal here is to have the captcha automatically refresh itself, if the captcha words submitted were wrong. So lets see how to do just that :
First, what you want to do is make sure that the UpdateMode for the updatepanel is set to conditional. This means, you are responsible for calling update on the updatepanel manually. We want to make this manual because if the captcha is invalid, then you do not want the updatepanel containing the captcha to refresh(this will only make recaptcha dissappear). Instead, we add a second updatepanel. Code speaks a thousand words, so lets take a look at functional code :
| ASP.NET |
|
<form runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" ChildrenAsTriggers="false" UpdateMode="Conditional" runat="server"> <ContentTemplate> <asp:TextBox ID="TextBoxComment" TextMode="MultiLine" Rows="5" Columns="35" runat="server"></asp:TextBox> <recaptcha:RecaptchaControl ID="recaptcha1" runat="server" Theme="red" PublicKey="6LcBAAAAAAAAAKtzVYRsIgOAAvCFge3iiMtf6hI9" PrivateKey="6LcBAAAAAAAAACQnFb_BI5tX7OxqC-C5RtROzx-S" /> <asp:UpdatePanel ID="UpdatePanel2" ChildrenAsTriggers="false" UpdateMode="Conditional" runat="server"> <ContentTemplate> <asp:Label ID="labelError" runat="server" EnableViewState="false" /> </ContentTemplate> </asp:UpdatePanel> <br /> <asp:Button ID="btnSubmit" ValidationGroup="GroupName" runat="server" Text="Submit" OnClick="btnSubmit_Click" /> </ContentTemplate> </asp:UpdatePanel> </form>
|
As you can note from the code above, we have two updatepanels. The second updatepanel contains a label to tell the user that the text they submitted is wrong. This is the only updatepanel we want to refresh when the captcha submitted is invalid.
Now the minimum c# code to do our bidding :
| C# |
|
void btnSubmit_Click(object sender, EventArgs args) { if (!recaptcha1.IsValid) { labelError.Text = "Incorrect, try again!"; labelError.ForeColor = System.Drawing.Color.Red; //Reload recaptcha ScriptManager.RegisterClientScriptBlock(this.Page, this.Page.GetType(), "whatever1", "Recaptcha.reload();", true); UpdatePanel2.Update(); } }
|
As you can note from above, the main code of interest here is the
code we are registering via the ScriptManager, specifically ->
"Recaptcha.reload(); what this will do is reload the captcha on the
clientside when the second updatepanel refreshes whilst display an
error message to our clients telling them to retry the captcha. I would
love to make this article longer than it already is, however that's
about it 
Screen shots of what it looks like before we submit and what it looks like after below :
After : note how the captcha is successfully reloaded via a partial postback.
Update 26-september-2008 : The full source to the example code i have used throughout this posting :
| ASP.NET |
|
<%@ Page Language="C#" %> <%@ Register TagPrefix="recaptcha" Namespace="Recaptcha" Assembly="Recaptcha" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> void btnSubmit_Click(object sender, EventArgs args) { if (!recaptcha1.IsValid) { labelError.Text = "Incorrect, try again!"; labelError.ForeColor = System.Drawing.Color.Red; //Reload recaptcha ScriptManager.RegisterClientScriptBlock(this.Page, this.Page.GetType(), "whatever1", "Recaptcha.reload();", true); UpdatePanel2.Update(); } } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="Form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" ChildrenAsTriggers="false" UpdateMode="Conditional" runat="server"> <ContentTemplate> <asp:TextBox ID="TextBoxComment" TextMode="MultiLine" Rows="5" Columns="35" runat="server"></asp:TextBox> <recaptcha:RecaptchaControl ID="recaptcha1" runat="server" Theme="red" PublicKey="6LcBAAAAAAAAAKtzVYRsIgOAAvCFge3iiMtf6hI9" PrivateKey="6LcBAAAAAAAAACQnFb_BI5tX7OxqC-C5RtROzx-S" /> <asp:UpdatePanel ID="UpdatePanel2" ChildrenAsTriggers="false" UpdateMode="Conditional" runat="server"> <ContentTemplate> <asp:Label ID="labelError" runat="server" EnableViewState="false" /> </ContentTemplate> </asp:UpdatePanel> <br /> <asp:Button ID="btnSubmit" ValidationGroup="GroupName" runat="server" Text="Submit" OnClick="btnSubmit_Click" /> </ContentTemplate> </asp:UpdatePanel> </form> </body> </html>
|