I have never implemented Google Captcha before, so I am unaware of what the problem is. When I submit the form, sometimes it works and sometimes it doesn't. If I submit the form without checking the captcha box and then click the captcha box when it sends me back to the page, it does not send the email. Any idea on how I can fix this issue?
My code behind:
protected static string ReCaptcha_Key = "<key>";
protected static string ReCaptcha_Secret = "<key>";
public bool IsReCaptchValid()
{
var result = false;
var captchaResponse = Request.Form["g-recaptcha-response"];
var secretKey = ReCaptcha_Secret;
var apiUrl = "https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}";
var requestUri = string.Format(apiUrl, secretKey, captchaResponse);
var request = (HttpWebRequest)WebRequest.Create(requestUri);
using (WebResponse response = request.GetResponse())
{
using (StreamReader stream = new StreamReader(response.GetResponseStream()))
{
JObject jResponse = JObject.Parse(stream.ReadToEnd());
var isSuccess = jResponse.Value<bool>("success");
result = (isSuccess) ? true : false;
}
}
return result;
}
protected void btnSend_Click(object sender, EventArgs e)
{
string Name = txtName.Text;
string EmailAddress = txtEmail.Text;
string phone = "Number not supplied";
if(txtPhone.Text != "")
{
phone = txtPhone.Text;
}
string SendAddress = @"<email address>";
string Subject = "Message from " + Name + " Top Tree Fellas Website";
string Message = Regex.Replace(txtMsg.Text, @"\r\n?|\n", "<br />");
if (String.IsNullOrEmpty(Name) || String.IsNullOrEmpty(EmailAddress) || String.IsNullOrEmpty(Message) || !(IsReCaptchValid()))
{
lblError.Text = "Please ensure all required fields are filled in.";
}
else
{
try
{
MailMessage msg = new MailMessage();
msg.To.Add(new MailAddress(@"<email address>"));
msg.Subject = Subject;
msg.From = new MailAddress(SendAddress);
msg.IsBodyHtml = true;
msg.Body = "<p><strong>Contact Name:</strong> " + Name + "<br />";
msg.Body += "<strong>Email Address:</strong> " + EmailAddress + "<br />";
msg.Body += "<strong>Phone:</strong> " + phone + "<br />";
msg.Body += "<strong>Message:</strong><br />" + Message + "</p>";
msg.ReplyToList.Add(new MailAddress(EmailAddress));
SmtpClient smtpClnt = new SmtpClient("smtp.ionos.co.uk");
smtpClnt.UseDefaultCredentials = false;
smtpClnt.Port = 587;
smtpClnt.Credentials = new NetworkCredential(@"<email address>", "<password>");
smtpClnt.EnableSsl = true;
smtpClnt.Send(msg);
lblError.ForeColor = System.Drawing.Color.Green;
txtName.Text = "";
txtEmail.Text = "";
txtMsg.Text = "";
txtPhone.Text = "";
Response.Write("<script>alert('Message sent');</script>");
}
catch (Exception er)
{
string er1 = er.Message + "<br />" + er.InnerException;
lblError.Text = er1;
Response.Write("<script>alert('Something went wrong. Please try again later or call us on: 0<phone number>');</script>");
}
}
}
My markup:
<script src='https://www.google.com/recaptcha/api.js'></script>
<div class="g-recaptcha" data-type="image" data-sitekey="6LfDHwcpAAAAAL71bUOZ4291MqxqDyTfvGbzOMcg"></div>
<asp:Button ID="btnSend" runat="server" ValidationGroup="vldContact" Text="Send your message" CssClass="btn btn-danger" OnClick="btnSend_Click" />
My webconfig:
<system.net>
<defaultProxy>
<proxy usesystemdefault = "false" bypassonlocal="false" proxyaddress="http://ntproxyus.lxa.perfora.net:3128"/>
</defaultProxy>
</system.net>
The exception I get:
Failure sending mail.
System.IO.IOException: Unable to read data from the transport connection: An established connection was aborted by the software in your host machine. ---> System.Net.Sockets.SocketException: An established connection was aborted by the software in your host machine at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) --- End of inner exception stack trace --- at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count) at System.Net.Security._SslStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security._SslStream.StartReading(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security._SslStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.TlsStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.Net.Mail.SmtpPooledStream.Dispose(Boolean disposing) at System.IO.Stream.Close() at System.IO.Stream.Dispose() at System.Net.ConnectionPool.Destroy(PooledStream pooledStream) at System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse) at System.Net.Mail.SmtpConnection.GetConnection(ServicePoint servicePoint) at System.Net.Mail.SmtpTransport.GetConnection(ServicePoint servicePoint) at System.Net.Mail.SmtpClient.GetConnection() at System.Net.Mail.SmtpClient.Send(MailMessage message)
The SmtpClient doesn't look to be getting cleaning up and the multiple handles/connections may be getting referenced in a secondary call when a previous reference to the Client finally gets garbage collected.
Try ensuring the SmtpClient gets disposed:
using (SmtpClient smtpClnt = new SmtpClient("smtp.ionos.co.uk"))
{
smtpClnt.UseDefaultCredentials = false;
smtpClnt.Port = 587;
smtpClnt.Credentials = new NetworkCredential(@"<email address>", "<password>");
smtpClnt.EnableSsl = true;
smtpClnt.Send(msg);
}