Simple Google ReCaptcha validation
private readonly string _ReCaptchaSecret;
private readonly string _ReCaptchaSiteKey;


private fields are either lowerCamelCase or _lowerCamelCase, both conventions are common.



public ReCaptchaValidator(string reCaptchaSecret)
{
    _ReCaptchaSecret = reCaptchaSecret;
    this.ErrorCodes = new List&lt;string&gt;();
}
public ReCaptchaValidator(string reCaptchaSecret, string reCaptchaSiteKey)
{
    _ReCaptchaSecret = reCaptchaSecret;
    _ReCaptchaSiteKey = reCaptchaSiteKey;
    this.ErrorCodes = new List&lt;string&gt;();
}


Don't repeat work in your constructors: use chaining instead.

public ReCaptchaValidator(string reCaptchaSecret)
{
    _ReCaptchaSecret = reCaptchaSecret;
    this.ErrorCodes = new List&lt;string&gt;();
}

public ReCaptchaValidator(string reCaptchaSecret, string reCaptchaSiteKey) 
    : this (reCaptchaSecret)
{
    _ReCaptchaSiteKey = reCaptchaSiteKey;
}




With C# 6, you can also use a property initializer to.. initialize.. your property.

public List&lt;string&gt; ErrorCodes { get; set; }

public ReCaptchaValidator(string reCaptchaSecret)
{
    _ReCaptchaSecret = reCaptchaSecret;
    this.ErrorCodes = new List&lt;string&gt;();
}


becomes

public List&lt;string&gt; ErrorCodes { get; set; } = new List&lt;string&gt;();

public ReCaptchaValidator(string reCaptchaSecret)
{
    _ReCaptchaSecret = reCaptchaSecret;
}




I would also advise to use a private setter for your ErrorCodes like this:

public List&lt;string&gt; ErrorCodes { get; private set; } = new List&lt;string&gt;();


Likewise, with C# 6, you might as well make it a readonly property:

public List&lt;string&gt; ErrorCodes { get; } = new List&lt;string&gt;();




StringBuilders see their most use when you're concatenating strings in a loop. In this scenario I would use a formatted string which turns this:

var sb = new StringBuilder();
sb.Append("https://www.google.com/recaptcha/api/siteverify?secret=");
sb.Append(_ReCaptchaSecret);
sb.Append("&amp;response=");
sb.Append(request.Form["g-recaptcha-response"]);
sb.Append("&amp;remoteip=");
sb.Append(GetUserIp(request));


into this:

var uri = string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&amp;response={1}&amp;remoteip={2}",
    _ReCaptchaSecret, 
    request.Form["g-recaptcha-response"], 
    GetUserIp(request));


Or with C# 6:

var uri = $"https://www.google.com/recaptcha/api/siteverify?secret={_ReCaptchaSecret}&amp;response={(request.Form["g-recaptcha-response"])}&amp;remoteip={GetUserIp(request)}";




else if (!string.IsNullOrEmpty(request.UserHostAddress))


I prefer string.IsNullOrWhiteSpace because only rarely whitespace characters are considered good input.