我在Azure云中托管的MVC4应用程序中使用ReCAPTCHA来为一个只有一个注册表单的简单网站进行保护。目前每小时大约有100-120个成功的注册。问题是,日志中出现了数百个System.Net.Sockets.SocketException: 远程主机强制关闭了一个现有的连接
错误,并且这个数字还在迅速增长:
System.Net.Http.HttpRequestException: An error occurred while sending the request. --->
System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. --->
System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. --->
System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
at System.Net.Connection.ReadCallback(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at My.Web.Infrastructure.Filters.ValidateReCaptchaAttribute.OnActionExecuting(ActionExecutingContext filterContext) in My.Web\Infrastructure\Filters\ValidateReCaptchaAttribute.cs:line 49 --->
(Inner Exception #0) System.Net.Http.HttpRequestException: An error occurred while sending the request. --->
System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. --->
System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. --->
System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
我用以下方法使用属性来验证验证码(删除了一些不重要的细节):
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class ValidateReCaptchaAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var formValues = new[]
{
new KeyValuePair<string, string>("privatekey", ConfigurationProvider.ReCaptchaPrivateKey),
new KeyValuePair<string, string>("remoteip", remoteIp.ToString()),
new KeyValuePair<string, string>("challenge", challengeField),
new KeyValuePair<string, string>("response", responseField)
};
try
{
using (var client = HttpClientFactory.Create())
using (var data = new FormUrlEncodedContent(formValues))
using (var response = client.PostAsync("http://www.google.com/recaptcha/api/verify", data).Result)
{
var responseString = response.Content.ReadAsStringAsync().Result;
if (responseString.StartsWith("true") == false)
{
modelState.AddModelError(string.Empty, DisplayName.Validation_CaptchaMissing);
}
}
}
catch (Exception ex)
{
log4net.LogManager.GetLogger("WebLogger").Error(string.Format("ValidateReCaptcha failed on {0}/{1}. {2}", controller, action, formValuesRaw), ex);
modelState.AddModelError(string.Empty, DisplayName.Validation_CaptchaMissing);
}
}
}
它在
var response = client.PostAsync()
这一行失败。不是总是这样。我无法在本地重现它。但它几乎对网站的每个用户都会失败 - 有时一次,有时两次,有时更多。最终他们能够注册 - 如我所说,我每小时看到超过100个注册 - 但那导致该小时日志表中出现300-400个错误。我尝试进行注册 - 虽然我百分之百确定我正确输入了验证码,但我仍然收到验证错误。
有任何想法吗?我的验证属性是否正常?还可能有其他原因吗?