Google reCAPTCHA in .NET ASPX

This post is using Microsoft .NET in C# with Visual Studio Community 2015 edition.

Google reCAPTCHA
Google reCAPTCHA

Google has a client side implementation for their reCAPTCHA on your web pages. Their documentation is great at explaining what it is, but it lacks in specific examples for how to implement in different environments. This causes confusion with some developers when they paste the two lines of code in their web page, but they are still able to submit the page, even when they don’t fill in the CAPTCHA.

There are a few Nuget packages that have widget wrappers, but that’s not really necessary.

Another issue is that there is an older Version 1.0 and the newer 2.0 (“I’m not a robot”) implementation. I think most folks would prefer the newer one.

Also, I’ve noticed during testing that it may be easily possible to get through the CAPTCHA the first time. On subsequent requests, probably based on IP address, it creates a popup that you have to select photos from. That should stop most bot engines. Just mentioning so you don’t think there’s a problem if you still occasionally get a form submit that looks like it could be a bot.

The getting started section of the Google Developer’s Guide is fine for getting started, but I’ll still cover it here, as I strongly dislike blog posts that only show 80% of the solution.

First thing you need is the actual URL that your going to deploy the application on. So if you haven’t registered one yet, you should do that now. I don’t know how Google handles it when two people try to register the same domain with reCAPTCHA, but I would assume that it would be questioned at some level. Maybe I’ll do an investigation in the future when I’m bored. I just feel that I don’t want to setup a domain under my Google account and then find out later someone else registered the domain and I’ve made a potential problem for them.

Okay, so let’s get started:

  1. Register your domain, as previously mentioned.
  2. Sign up for your reCAPTCHA at Google.
    1. Save your site and private/secret key somewhere in your source control
  3. Right click on your solution and select “Manage NuGet Packages for Solution…”
    1. Click on “Browse”
    2. Search for “Newtonsoft.Json”
    3. Highlight it in the results
    4. Check the box next to your Web Application and click “Install”
  4. Place the script call on your page, preferably in the header, but it doesn’t have to be if you use master pages etc. I have it right after the asp:Content start key.
<script src="https://www.google.com/recaptcha/api.js" async defer></script>

NOTE: My IntelliSense in VS recognizes the two keywords “async” and “defer”, but still flags them with an HTML5 warning. You can ignore this.

5. WITHIN THE FORM TAGS of your page, place the widget. This is the “Implicit” method of displaying the reCAPTCHA widget.

<form runat="server" class="form-horizontal">
	<div class="g-recaptcha" data-sitekey="Site_Key_Provided_By_Google"><div>
<form>

6. Create a class to hold the response from Google

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace TimeTracker.web
{
	public class CaptchaResponse
	{

		[JsonProperty("success")]
		public bool Success { get; set; }

		[JsonProperty("error-codes")]
		public List<string> ErrorCodes { get; set; }

		[JsonProperty("challenge_ts")]
		public DateTime TimeStamp { get; set; }

		[JsonProperty("hostname")]
		public string HostName { get; set; }

	}
}
  1. Create a private method in your code behind to verify the reCAPTCHA
/// <summary>
/// Check if the reCAPTCHA challenge was successful
/// </summary>
/// <returns></returns>
private bool VerifyCaptcha()
{
	var response = Request.Form["g-Recaptcha-Response"];
	string secret = "Your_Private/Secret_Key_From_Google";

	var client = new WebClient();
	var reply = client.DownloadString(
				string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}",
								secret, response));

	CaptchaResponse captchaResponse = JsonConvert.DeserializeObject<CaptchaResponse>(reply);

	// Optionaly, look for messages if response is false, caution, response collection could still be null
	if (!captchaResponse.Success)
	{
		return false;
	}

	return true;

}
  1. Handle the checking in your button submit event
protected void btnSubmit_Click(object sender, EventArgs e)
{
	if (VerifyCaptcha())
	{
		Response.Redirect("Your_SubmitSuccessPage.aspx");
	}
	else
	{
		// Send shock to user's chair
	}
}

The version 1.0 of reCAPTCHA used to allow you to debug using localhost without issue. The new version doesn’t. I can only assume that this was done for security reasons.

Update: If you add localhost as an approved domain in the reCAPTCHA setup, you should be able to debug locally.

I hope that this post helps you to get up and running quickly with Google’s reCAPTCHA without the two or three hours of frustration that I had.

Trim a String to a Particular Length

One piece of code that is very popular, besides checking for null, is being able to trim a string to a particular length, making sure a string is not too long to save in the database or display on your page or MVC View. In the olden days, we had lots of code like this:

if (myString.Length > 10)
{
	dbTable.Property = myString.Substring(0,10);
}
else
{
	dbTable.Property = myString;
}

In one form or another. Now, with extension methods, we can add this into our bag of tricks to have available everywhere:

public static class StringExtensions
{
	public static string Trim(this string value, int MaxLength)
	{
		return value.Substring(0, Math.Min(MaxLength, value.Length));
	}
}

Notice that I’m using the Math.Min function to tell the Substring whether to return the string as it is, or use the MaxLength argument. Now the code above will look like this:

dbTable.Property = myString.Trim(10);

And it will save the value of myString as it’s current value, unless it’s longer than 10, which will cause it to be trimmed.

One of the big advantages of using String Extension Methods like this is that they can be used in Linq queries very easily. If you want to see more about extension methods, check out my other posts below:

Display SQL for LINQ to Entities

If you’re fluent in SQL and want to display SQL for LINQ to Entities in your .NET application, there are ways to do it. It heavily depends on the version of Entity Framework you’re using

I was looking for a way to display the SQL behind a LINQ to entities query in the immediate window. Lots of sites have some code, except they didn’t seem to work for me ☹.

In Entity Framework version 6.0, you can use the following code. You have to make sure that you don’t have your LINQ query ending with anything that will cause the query to execute, such as .ToList().

((System.Linq.IQueryable) %queryvar%).ToString()

You can use this right in the immediate window. Here is another that I found on the web that didn’t work for me for whatever reason. I think ObjectQuery is not in that library any longer:

((System.Data.Objects.ObjectQuery) %queryvar%).ToTraceString()

If you don’t mind changing your code, there is a way to display the query in the Output windows (after it executes) with this code Added before your SaveChanges().

context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);

For Entity Framework Core, version 6.x, they have added a DebugView property in Visual Studio so that you can inspect the query at a stop point. If you want to get the query in code, you can use this:

string _myQuery = _entityrows.ToQueryString();

Keep on LINQing!

Multiple App.Config files

Visual studio has had the ability to have multiple Web.config files for some time now. What about the need for multiple App.config files. Many posts online talk about Unit.Test apps, which is a great application for this, but some of us old guys still automate business processes and could really use multiple app.config files for deploying Windows Services too.

The technique here is is not the same as a Web.config transformation. In a transformation, you only put the exceptions in your sub Web.config’s using a replacement line in your Web.Release.config such as:

<appSettings xdt:Transform="Replace">

This technique is different, in that you must provide a complete copy of the .config file that you want for each type of build. While this is a maintenance issue, I highly suggest that you put comments in your .configs to remind folks to add their new or modified entries to each config. I think this is less of an issue then continually releasing a Windows Service that has the wrong file paths for your file import service.

You’ll need to edit your .csproj file manually. Make sure you don’t accidentally add this to the .csproj.vspscc file.  In many version of Visual Studio, you’ll already see a section at the bottom that is commented out.

<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->

Replace the “AfterBuild” section with the following entry, un-commenting it of course:.

<Target Name="AfterBuild">
<Delete Files="$(TargetDir)$(TargetFileName).config" />
<Copy SourceFiles="$(ProjectDir)\Config\App.$(Configuration).config"
DestinationFiles="$(TargetDir)$(TargetFileName).config" />
</Target>

Now open your project and create a “Config” folder to match the entry we just put in the .csproj file. If you already have an App.config file, copy it to the \Config folder and rename it App.Debug.config. Then copy it to the other build types that you have, for instance App.Release.config and App.UAT.config.

Edit each one and remove any commented entries you have that are not appropriate for the particular release that you’re building.

I recommend putting something like this in the top of each .config file:

<!-- This file is copied and renamed by the 'AfterBuild' MSBuild task -->

<!-- Make sure that any changes you make to this file you also propagate to
the other file in the \Config folder -->

Saving Child Objects in Entity Framework

Trying to work with Entity Framework in a normalized database can pose a little learning curve as the the intricacies of the ORM.

Trying to work with Entity Framework in a normalized database can pose a little learning curve as due to the intricacies of the ORM. As an example, most of my business objects have child collections, as I assume yours do as well. A user has phones, addresses, orders etc. When I call up a user, I usually want all these sub collections as well.

In most cases, my applications have a web service in between the repository and the user interface. This means that I’m working detached from the ORM. Usually having the Entities mapped to more well structured business objects in the Service layer as well.

So what happens when I call up a user and we want to modify an address, or add a new address? Well, let’s take a look.

First, I have a database with two tables that both have Primary Keys and a Foreign Key relationship.

The Address.CustId in the Addresses table is linked to the Customer.Id primary key. If I run a query on the database as below, you can see the data:

SELECT c.Id as CustID, c.Name, a.Id as AddId
		, a.Address1, a.CustId
FROM [lookupsdemo].[dbo].[Customers] c
	JOIN [lookupsdemo].[dbo].[Addresses] a
ON c.Id = a.CustId

The data this produces is:

So now let’s say I want to update an address. According the Microsoft, this is easy, just write some code like:

Models.Customer _cust = new Models.Customer() { Id = 2, Name = "Jim Beam" };
Models.Address _add = new Models.Address() { Id = 2, Address1 = "1601 Penn Ave", CustId = 2 };
_cust.Addresses.Add(_add);

Models.lookupsdemoEntities _entities = new Models.lookupsdemoEntities();
_entities.Customers.Attach(_cust);
_entities.Entry(_cust).State = System.Data.Entity.EntityState.Modified;
_entities.SaveChanges();

Life should be good, after running this code. The data looks like:

What? Looks like the name was updated, but not the address. Well, it turns out that marking the parent object as EntityState.Modified does not have any effect on the child objects.

Let’s modify the code a bit and see what happens:


Models.Customer _cust = new Models.Customer() { Id = 2, Name = "Jim Beam 2" };
Models.Address _add = new Models.Address() { Id = 2, Address1 = "1602 Penn Ave", CustId = 2 };
_cust.Addresses.Add(_add);

Models.lookupsdemoEntities _entities = new Models.lookupsdemoEntities();
_entities.Customers.Attach(_cust);
_entities.Entry(_cust).State = System.Data.Entity.EntityState.Modified;

foreach(Models.Address _item in _cust.Addresses)
{
	_entities.Addresses.Attach(_item);
	_entities.Entry(_item).State = System.Data.Entity.EntityState.Modified;
}

_entities.SaveChanges();

Alright, after running this code, let’s see what we have:

Well now, we finally got what we wanted, Jim’s name and Address1 have been updated!

What if we went to add a new address you ask. Well, just for fun, I threw in the code like this:


Models.Customer _cust = new Models.Customer() { Id = 2, Name = "Jim Beam 2" };
Models.Address _add = new Models.Address() { Id = 2, Address1 = "1602 Penn Ave", CustId = 2 };
Models.Address _add1 = new Models.Address() { Id = 0, Address1 = "1400 Fun Street", CustId = 2 };
_cust.Addresses.Add(_add);
_cust.Addresses.Add(_add1);

Models.lookupsdemoEntities _entities = new Models.lookupsdemoEntities();
_entities.Customers.Attach(_cust);
_entities.Entry(_cust).State = System.Data.Entity.EntityState.Modified;

foreach(Models.Address _item in _cust.Addresses)
{
	_entities.Addresses.Attach(_item);
	_entities.Entry(_item).State = System.Data.Entity.EntityState.Modified;
}

_entities.SaveChanges();

Anybody want to bet a dollar on whether this worked? Well, you’re lucky, because you would have lost your dollar. This results in a System.Data.Entity.Infrastructure.DbUpdateConcurrencyException.

I’ve modified the code to use a marker to tell if the child collection items are modifications or additions, here I’m using the Id > 0 to assume these are mods, all others are adds.


Models.Customer _cust = new Models.Customer() { Id = 2, Name = "Jim Beam 3" };
Models.Address _add = new Models.Address() { Id = 2, Address1 = "1603 Penn Ave", CustId = 2 };
Models.Address _add1 = new Models.Address() { Id = 0, Address1 = "1400 Fun Street", CustId = 2 };
_cust.Addresses.Add(_add);
_cust.Addresses.Add(_add1);

Models.lookupsdemoEntities _entities = new Models.lookupsdemoEntities();
_entities.Customers.Attach(_cust);
_entities.Entry(_cust).State = System.Data.Entity.EntityState.Modified;

foreach(Models.Address _item in _cust.Addresses)
{
	if (_item.Id > 0)
	{
		_entities.Addresses.Attach(_item);
		_entities.Entry(_item).State = System.Data.Entity.EntityState.Modified;
	}
	else
	{
		_entities.Addresses.Add(_item);
	}
}

_entities.SaveChanges();

This gets us everything we wanted. We get the parent modifications, as well as the address modification and the new address.

As you can see that Jim is happy with both of his addresses.

It’s a little more code than I would like to use, but in the long run, it’s still less than coding a SQLClient Command with stored procedures.

Extension Method to Convert Types

I was working on a project where I needed to compare values from two different systems. I needed a way to convert the data based on the type, which was known, from a string value that was pulled from XML or typed in by the user as an override value. Using LINQ to compare the values was problematic, as a decimal value could be input as “0” or “0.0” or “0.00” etc. Dates are an obvious issue. So I used an extension method to convert types.

Let’s take a look at the following code:


private void ConvertDecimals1()
{
	try
	{
		string[] valsFromXML = new string[] {"0", "1", "2" };
		string testVal = "0.00";

		var myVals = from objVal in valsFromXML
					 where objVal == testVal
					 select objVal;

		Console.WriteLine(myVals.Count().ToString());

	}
	catch (Exception)
	{ throw; }
}

Running this code produces a count of zero, which you would expect for a comparison of this nature. But wait, System.String implements IComparable, so maybe we could use it to quickly resolve our issue:

var myVals = from objVal in valsFromXML
			 where (objVal.CompareTo(testVal) == 0)
			 select objVal;

But alas, no easy solution here, this also does not produce a match, unless the strings were formatted identically. There is no getting around converting the values. Fortunately, we have some conversion functions that we could use to accomplish this task:

var myVals = from objVal in valsFromXML
			 where Convert.ToDecimal(objVal) == Convert.ToDecimal(testVal)
			 select objVal;

Ah, perfect this produces the count of one that we were looking for. This code will work great, so long as it never has a code review or goes into production. Since the source values are strings, you don’t have any control over what is being passed in. In this case, the best bet is to use the TryParse method on the type to convert the values:

decimal decValue;
decimal.TryParse(testVal, out decValue);

Which would work great, except we still have the collection of values being passed in that would have to be handled in a foreach loop to accomplish this goal.

Extension methods to the rescue again. Let’s create a new static class and encapsulate the logic we need to convert the string to the decimal values:

public static class ExtMethods
{
	public static decimal? ToDecimal(this string value)
	{
		Decimal decItem;
		if (Decimal.TryParse(value, out decItem))
		{ return decItem; }
		else
		{ return null; }
	}
}

This effectively adds the ability to attempt to convert the string value to a decimal and return the value. Notice that I didn’t just return the decItem variable contents. This is because if the TryParse fails, it will fill the value with a decimal value of zero, which will pass a comparison to zero. This is not acceptable, so we still need to check that the conversion occurred successfully before we return the value. Returning null will not cause LINQ to raise an exception.

So now we can modify our LINQ query as follows:

var myVals = from objVal in valsFromXML
			 where objVal.ToDecimal() == testVal.ToDecimal()
			 select objVal;

This will give us a safe, encapsulated, reusable way to compare values that need to be converted from strings.

List Shuffle / Random Order

Had a project where we needed to be able to process items in a list in random order. The implementation of the random order was a little verbose. This extension method on IList<T> works pretty well for me.

static readonly Random _random = new();

/// <summary>
/// This is a Shuffle extension to shuffle the order of Lists randomly
/// </summary>
/// <typeparam name="T"><typeparam>
/// <param name="list"></param>
public static void Shuffle<T>(this IList<T> list)
{
	int intListCount = list.Count;
	while (intListCount > 1)
	{
		intListCount--;
		int intRandom = _random.Next(intListCount + 1);
		T value = list[intRandom];
		list[intRandom] = list[intListCount];
		list[intListCount] = value;
	}
}

The above sample uses the System.Random implementation to retrieve a random number by passing in the count of the list + 1. The reason I’m adding 1 here is because the Next method is zero (0) based, so it will return a number from 0 to your list count – 1. There is another overload that you can pass in the starting value and the ending value.

int intRandom = _random.Next(1, intListCount);

So this extension method will shuffle your list and give you back a list that is in random order each time.

If you’d like to see more extension methods, take a look at my post Jack’s Top 10 String Extension Methods