[HttpPost]
[ReCaptcha]
public ActionResult MyAction(MyModel model)
{
if (!ModelState.IsValid) // Will have a Model Error "ReCaptcha" if the user input is incorrect
return Json(new { capthcaInvalid = true });
... other stuff ...
}
I have added reCaptcha to a project I'm currently working on. I needed it to use the AJAX API as the reCaptcha element was loaded into the page dynamically. I couldn't find any existing controls and the API is simple so I created my own.
I'll post my code here in case anyone finds it useful.
[HttpPost]
[ReCaptcha]
public ActionResult MyAction(MyModel model)
{
if (!ModelState.IsValid) // Will have a Model Error "ReCaptcha" if the user input is incorrect
return Json(new { capthcaInvalid = true });
... other stuff ...
}
6: Note you will need to reload the captcha after each post even if it was valid and another part of the form was invalid. Use Recaptcha.reload();
[CaptchaValidator(
PrivateKey = "your private reCaptcha Google Key",
ErrorMessage = "Invalid input captcha.",
RequiredMessage = "The captcha field is required.")]
public ActionResult MyAction(myVM model)
{
if (ModelState.IsValid) //this will take care of captcha
{
}
}
,或者
public ActionResult MyAction(myVM model, bool captchaValid)
{
if (captchaValid) //manually check for captchaValid
{
}
}
Simple and Complete Solution working for me.
Supports ASP.NET MVC 4 and 5 (Supports ASP.NET 4.0, 4.5, and 4.5.1)
Step 1: Install NuGet Package by "Install-Package reCAPTCH.MVC"
Step 2: Add your Public and Private key to your web.config file in appsettings section
Step 4: Implement the Controller Action that will handle the form submission and Captcha validation
[CaptchaValidator(
PrivateKey = "your private reCaptcha Google Key",
ErrorMessage = "Invalid input captcha.",
RequiredMessage = "The captcha field is required.")]
public ActionResult MyAction(myVM model)
{
if (ModelState.IsValid) //this will take care of captcha
{
}
}
OR
public ActionResult MyAction(myVM model, bool captchaValid)
{
if (captchaValid) //manually check for captchaValid
{
}
}
public class HomeController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ContactSubmit(
[Bind(Include = "FromName, FromEmail, FromPhone, Message, ContactId")]
ContactViewModel model)
{
if (!await RecaptchaServices.Validate(Request))
{
ModelState.AddModelError(string.Empty, "You have not confirmed that you are not a robot");
}
if (ModelState.IsValid)
{
...
ExampleView.cshtml
@model MyMvcApp.Models.ContactViewModel
@*This is assuming the master layout places the styles section within the head tags*@
@section Styles {
@Styles.Render("~/Content/ContactPage.css")
<script src='https://www.google.com/recaptcha/api.js'></script>
}
@using (Html.BeginForm("ContactSubmit", "Home",FormMethod.Post, new { id = "contact-form" }))
{
@Html.AntiForgeryToken()
...
<div class="form-group">
@Html.LabelFor(m => m.Message)
@Html.TextAreaFor(m => m.Message, new { @class = "form-control", @cols = "40", @rows = "3" })
@Html.ValidationMessageFor(m => m.Message)
</div>
<div class="row">
<div class="g-recaptcha" data-sitekey='@System.Configuration.ConfigurationManager.AppSettings["RecaptchaClientKey"]'></div>
</div>
<div class="row">
<input type="submit" id="submit-button" class="btn btn-default" value="Send Your Message" />
</div>
}
RecaptchaServices.cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web;
using System.Configuration;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using System.Runtime.Serialization;
namespace MyMvcApp.Services
{
public class RecaptchaServices
{
//ActionFilterAttribute has no async for MVC 5 therefore not using as an actionfilter attribute - needs revisiting in MVC 6
internal static async Task<bool> Validate(HttpRequestBase request)
{
string recaptchaResponse = request.Form["g-recaptcha-response"];
if (string.IsNullOrEmpty(recaptchaResponse))
{
return false;
}
using (var client = new HttpClient { BaseAddress = new Uri("https://www.google.com") })
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("secret", ConfigurationManager.AppSettings["RecaptchaSecret"]),
new KeyValuePair<string, string>("response", recaptchaResponse),
new KeyValuePair<string, string>("remoteip", request.UserHostAddress)
});
var result = await client.PostAsync("/recaptcha/api/siteverify", content);
result.EnsureSuccessStatusCode();
string jsonString = await result.Content.ReadAsStringAsync();
var response = JsonConvert.DeserializeObject<RecaptchaResponse>(jsonString);
return response.Success;
}
}
[DataContract]
internal class RecaptchaResponse
{
[DataMember(Name = "success")]
public bool Success { get; set; }
[DataMember(Name = "challenge_ts")]
public DateTime ChallengeTimeStamp { get; set; }
[DataMember(Name = "hostname")]
public string Hostname { get; set; }
[DataMember(Name = "error-codes")]
public IEnumerable<string> ErrorCodes { get; set; }
}
}
}
web.config
<configuration>
<appSettings>
<!--recaptcha-->
<add key="RecaptchaSecret" value="***secret key from https://developers.google.com/recaptcha***" />
<add key="RecaptchaClientKey" value="***client key from https://developers.google.com/recaptcha***" />
</appSettings>
</configuration>
An async version for MVC 5 (i.e. avoiding ActionFilterAttribute, which is not async until MVC 6) and reCAPTCHA 2
ExampleController.cs
public class HomeController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ContactSubmit(
[Bind(Include = "FromName, FromEmail, FromPhone, Message, ContactId")]
ContactViewModel model)
{
if (!await RecaptchaServices.Validate(Request))
{
ModelState.AddModelError(string.Empty, "You have not confirmed that you are not a robot");
}
if (ModelState.IsValid)
{
...
ExampleView.cshtml
@model MyMvcApp.Models.ContactViewModel
@*This is assuming the master layout places the styles section within the head tags*@
@section Styles {
@Styles.Render("~/Content/ContactPage.css")
<script src='https://www.google.com/recaptcha/api.js'></script>
}
@using (Html.BeginForm("ContactSubmit", "Home",FormMethod.Post, new { id = "contact-form" }))
{
@Html.AntiForgeryToken()
...
<div class="form-group">
@Html.LabelFor(m => m.Message)
@Html.TextAreaFor(m => m.Message, new { @class = "form-control", @cols = "40", @rows = "3" })
@Html.ValidationMessageFor(m => m.Message)
</div>
<div class="row">
<div class="g-recaptcha" data-sitekey='@System.Configuration.ConfigurationManager.AppSettings["RecaptchaClientKey"]'></div>
</div>
<div class="row">
<input type="submit" id="submit-button" class="btn btn-default" value="Send Your Message" />
</div>
}
RecaptchaServices.cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web;
using System.Configuration;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using System.Runtime.Serialization;
namespace MyMvcApp.Services
{
public class RecaptchaServices
{
//ActionFilterAttribute has no async for MVC 5 therefore not using as an actionfilter attribute - needs revisiting in MVC 6
internal static async Task<bool> Validate(HttpRequestBase request)
{
string recaptchaResponse = request.Form["g-recaptcha-response"];
if (string.IsNullOrEmpty(recaptchaResponse))
{
return false;
}
using (var client = new HttpClient { BaseAddress = new Uri("https://www.google.com") })
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("secret", ConfigurationManager.AppSettings["RecaptchaSecret"]),
new KeyValuePair<string, string>("response", recaptchaResponse),
new KeyValuePair<string, string>("remoteip", request.UserHostAddress)
});
var result = await client.PostAsync("/recaptcha/api/siteverify", content);
result.EnsureSuccessStatusCode();
string jsonString = await result.Content.ReadAsStringAsync();
var response = JsonConvert.DeserializeObject<RecaptchaResponse>(jsonString);
return response.Success;
}
}
[DataContract]
internal class RecaptchaResponse
{
[DataMember(Name = "success")]
public bool Success { get; set; }
[DataMember(Name = "challenge_ts")]
public DateTime ChallengeTimeStamp { get; set; }
[DataMember(Name = "hostname")]
public string Hostname { get; set; }
[DataMember(Name = "error-codes")]
public IEnumerable<string> ErrorCodes { get; set; }
}
}
}
web.config
<configuration>
<appSettings>
<!--recaptcha-->
<add key="RecaptchaSecret" value="***secret key from https://developers.google.com/recaptcha***" />
<add key="RecaptchaClientKey" value="***client key from https://developers.google.com/recaptcha***" />
</appSettings>
</configuration>
// return ActionResult if you want
public string RecaptchaWork()
{
// Get recaptcha value
var r = Request.Params["g-recaptcha-response"];
// ... validate null or empty value if you want
// then
// make a request to recaptcha api
using (var wc = new WebClient())
{
var validateString = string.Format(
"https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}",
"your_secret_key", // secret recaptcha key
r); // recaptcha value
// Get result of recaptcha
var recaptcha_result = wc.DownloadString(validateString);
// Just check if request make by user or bot
if (recaptcha_result.ToLower().Contains("false"))
{
return "recaptcha false";
}
}
// Do your work if request send from human :)
}
Step 1: Client site integration
Paste this snippet before the closing </head> tag on your HTML template:
When your users submit the form where you integrated reCAPTCHA, you'll get as part of the payload a string with the name "g-recaptcha-response". In order to check whether Google has verified that user, send a POST request with these parameters:
// return ActionResult if you want
public string RecaptchaWork()
{
// Get recaptcha value
var r = Request.Params["g-recaptcha-response"];
// ... validate null or empty value if you want
// then
// make a request to recaptcha api
using (var wc = new WebClient())
{
var validateString = string.Format(
"https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}",
"your_secret_key", // secret recaptcha key
r); // recaptcha value
// Get result of recaptcha
var recaptcha_result = wc.DownloadString(validateString);
// Just check if request make by user or bot
if (recaptcha_result.ToLower().Contains("false"))
{
return "recaptcha false";
}
}
// Do your work if request send from human :)
}
''# fix SO code coloring issue.
<Extension()>
Public Function reCaptcha(ByVal htmlHelper As HtmlHelper) As MvcHtmlString
Dim captchaControl = New Recaptcha.RecaptchaControl With {.ID = "recaptcha",
.Theme = "clean",
.PublicKey = "XXXXXX",
.PrivateKey = "XXXXXX"}
Dim htmlWriter = New HtmlTextWriter(New IO.StringWriter)
captchaControl.RenderControl(htmlWriter)
Return MvcHtmlString.Create(htmlWriter.InnerWriter.ToString)
End Function
3] 从这里您需要一个可重复使用的服务器 此行上方的侧面验证器
Public Class ValidateCaptchaAttribute : Inherits ActionFilterAttribute
Private Const CHALLENGE_FIELD_KEY As String = "recaptcha_challenge_field"
Private Const RESPONSE_FIELD_KEY As String = "recaptcha_response_field"
Public Overrides Sub OnActionExecuting(ByVal filterContext As ActionExecutingContext)
If IsNothing(filterContext.HttpContext.Request.Form(CHALLENGE_FIELD_KEY)) Then
''# this will push the result value into a parameter in our Action
filterContext.ActionParameters("CaptchaIsValid") = True
Return
End If
Dim captchaChallengeValue = filterContext.HttpContext.Request.Form(CHALLENGE_FIELD_KEY)
Dim captchaResponseValue = filterContext.HttpContext.Request.Form(RESPONSE_FIELD_KEY)
Dim captchaValidtor = New RecaptchaValidator() With {.PrivateKey = "xxxxx",
.RemoteIP = filterContext.HttpContext.Request.UserHostAddress,
.Challenge = captchaChallengeValue,
.Response = captchaResponseValue}
Dim recaptchaResponse = captchaValidtor.Validate()
''# this will push the result value into a parameter in our Action
filterContext.ActionParameters("CaptchaIsValid") = recaptchaResponse.IsValid
MyBase.OnActionExecuting(filterContext)
End Sub
是可重用的 **一次**
此行下方的代码是一遍又一遍地实现 reCaptcha 是多么容易
现在您已经有了可重用的代码...您需要做的就是将验证码添加到你的观点。
<%: Html.reCaptcha %>
当您将表单发布到控制器时......
''# Fix SO code coloring issues
<ValidateCaptcha()>
<AcceptVerbs(HttpVerbs.Post)>
Function Add(ByVal CaptchaIsValid As Boolean, ByVal [event] As Domain.Event) As ActionResult
If Not CaptchaIsValid Then ModelState.AddModelError("recaptcha", "*")
'#' Validate the ModelState and submit the data.
If ModelState.IsValid Then
''# Post the form
Else
''# Return View([event])
End If
End Function
I've successfully implemented ReCaptcha in the following way. note: this is in VB, but can easily be converted
''# fix SO code coloring issue.
<Extension()>
Public Function reCaptcha(ByVal htmlHelper As HtmlHelper) As MvcHtmlString
Dim captchaControl = New Recaptcha.RecaptchaControl With {.ID = "recaptcha",
.Theme = "clean",
.PublicKey = "XXXXXX",
.PrivateKey = "XXXXXX"}
Dim htmlWriter = New HtmlTextWriter(New IO.StringWriter)
captchaControl.RenderControl(htmlWriter)
Return MvcHtmlString.Create(htmlWriter.InnerWriter.ToString)
End Function
3] From here you need a re-usable server side validator
Public Class ValidateCaptchaAttribute : Inherits ActionFilterAttribute
Private Const CHALLENGE_FIELD_KEY As String = "recaptcha_challenge_field"
Private Const RESPONSE_FIELD_KEY As String = "recaptcha_response_field"
Public Overrides Sub OnActionExecuting(ByVal filterContext As ActionExecutingContext)
If IsNothing(filterContext.HttpContext.Request.Form(CHALLENGE_FIELD_KEY)) Then
''# this will push the result value into a parameter in our Action
filterContext.ActionParameters("CaptchaIsValid") = True
Return
End If
Dim captchaChallengeValue = filterContext.HttpContext.Request.Form(CHALLENGE_FIELD_KEY)
Dim captchaResponseValue = filterContext.HttpContext.Request.Form(RESPONSE_FIELD_KEY)
Dim captchaValidtor = New RecaptchaValidator() With {.PrivateKey = "xxxxx",
.RemoteIP = filterContext.HttpContext.Request.UserHostAddress,
.Challenge = captchaChallengeValue,
.Response = captchaResponseValue}
Dim recaptchaResponse = captchaValidtor.Validate()
''# this will push the result value into a parameter in our Action
filterContext.ActionParameters("CaptchaIsValid") = recaptchaResponse.IsValid
MyBase.OnActionExecuting(filterContext)
End Sub
above this line is reusable **ONE TIME** code
below this line is how easy it is to implement reCaptcha over and over
Now that you have your re-usable code... all you need to do is add the captcha to your View.
<%: Html.reCaptcha %>
And when you post the form to your controller...
''# Fix SO code coloring issues
<ValidateCaptcha()>
<AcceptVerbs(HttpVerbs.Post)>
Function Add(ByVal CaptchaIsValid As Boolean, ByVal [event] As Domain.Event) As ActionResult
If Not CaptchaIsValid Then ModelState.AddModelError("recaptcha", "*")
'#' Validate the ModelState and submit the data.
If ModelState.IsValid Then
''# Post the form
Else
''# Return View([event])
End If
End Function
发布评论
评论(8)
有一些很好的例子:
之前这个 Stack Overflow 问题也对此进行了介绍。
适用于 MVC 4 和 5 的 NuGet Google reCAPTCHA V2
There are a few great examples:
This has also been covered before in this Stack Overflow question.
NuGet Google reCAPTCHA V2 for MVC 4 and 5
我已将 reCaptcha 添加到我当前正在进行的项目中。我需要它来使用 AJAX API,因为 reCaptcha 元素会动态加载到页面中。我找不到任何现有的控件,而且 API 很简单,所以我创建了自己的控件。
我将在这里发布我的代码,以防有人发现它有用。
1:将脚本标记添加到母版页标题
2:将密钥添加到 web.config
3:创建操作属性和 Html Helper 扩展 strong>
4:将验证码添加到您的视图
5:将属性添加到您的操作
6:请注意,您需要在每次发布后重新加载验证码,即使它是有效的,而表格的另一部分是无效的。使用Recaptcha.reload();
I have added reCaptcha to a project I'm currently working on. I needed it to use the AJAX API as the reCaptcha element was loaded into the page dynamically. I couldn't find any existing controls and the API is simple so I created my own.
I'll post my code here in case anyone finds it useful.
1: Add the script tag to the master page headers
2: Add your keys to the web.config
3: Create the Action Attribute and Html Helper extensions
4: Add the captcha to your view
5: Add the attribute to your action
6: Note you will need to reload the captcha after each post even if it was valid and another part of the form was invalid. Use
Recaptcha.reload();
简单而完整的解决方案对我有用。
支持 ASP.NET MVC 4 和 5(支持 ASP.NET 4.0、4.5 和 4.5.1)
第 1 步:通过“Install-Package reCAPTCH.MVC”安装 NuGet 包“
步骤2:在AppSettings部分中将您的公共和私钥添加到Web.config文件中
。 com/recaptcha/intro/index.html" rel="noreferrer">https://www.google.com/recaptcha/intro/index.html
然后单击页面顶部的“获取 reCAPTCHA”
第 3 步:修改表单以包含 reCaptcha
第 4 步:实施将处理表单提交和验证码验证的控制器操作
,或者
Simple and Complete Solution working for me.
Supports ASP.NET MVC 4 and 5 (Supports ASP.NET 4.0, 4.5, and 4.5.1)
Step 1: Install NuGet Package by "Install-Package reCAPTCH.MVC"
Step 2: Add your Public and Private key to your web.config file in appsettings section
You can create an API key pair for your site at https://www.google.com/recaptcha/intro/index.html
and click on Get reCAPTCHA at top of the page
Step 3: Modify your form to include reCaptcha
Step 4: Implement the Controller Action that will handle the form submission and Captcha validation
OR
MVC 5 的异步版本(即避免 ActionFilterAttribute,直到 MVC 6 才异步)和 reCAPTCHA 2
ExampleController.cs
ExampleView.cshtml
RecaptchaServices.cs
web.config
An async version for MVC 5 (i.e. avoiding ActionFilterAttribute, which is not async until MVC 6) and reCAPTCHA 2
ExampleController.cs
ExampleView.cshtml
RecaptchaServices.cs
web.config
第 1 步:客户端站点集成
将此代码段粘贴到 HTML 模板上的
结束标记之前:
将此代码段粘贴到
步骤 2:服务器站点集成
当您的用户提交集成了 reCAPTCHA 的表单时,您将获得一个名为“g-recaptcha-response”的字符串作为负载的一部分。要检查 Google 是否已验证该用户,请发送包含以下参数的 POST 请求:
URL : https: //www.google.com/recaptcha/api/siteverify
秘密:您的密钥
响应:“g-recaptcha-response”的值。
现在您的 MVC 应用程序正在运行:
Step 1: Client site integration
Paste this snippet before the closing
</head>
tag on your HTML template:Paste this snippet at the end of the
<form>
where you want the reCAPTCHA widget to appear:Step 2: Server site integration
When your users submit the form where you integrated reCAPTCHA, you'll get as part of the payload a string with the name "g-recaptcha-response". In order to check whether Google has verified that user, send a POST request with these parameters:
URL : https://www.google.com/recaptcha/api/siteverify
secret : your secret key
response : The value of 'g-recaptcha-response'.
Now in action of your MVC app:
我已经通过以下方式成功实现了 ReCaptcha。
注意:这是用 VB 编写的,但可以轻松转换
1] 首先获取 reCaptcha 库
2] 然后构建自定义 ReCaptcha HTML Helper
3] 从这里您需要一个可重复使用的服务器 此行上方的侧面验证器
是可重用的 **一次**
此行下方的代码是一遍又一遍地实现 reCaptcha 是多么容易
现在您已经有了可重用的代码...您需要做的就是将验证码添加到你的观点。
当您将表单发布到控制器时......
I've successfully implemented ReCaptcha in the following way.
note: this is in VB, but can easily be converted
1] First grab a copy of the reCaptcha library
2] Then build a custom ReCaptcha HTML Helper
3] From here you need a re-usable server side validator
above this line is reusable **ONE TIME** code
below this line is how easy it is to implement reCaptcha over and over
Now that you have your re-usable code... all you need to do is add the captcha to your View.
And when you post the form to your controller...
扩展 Magpie 的答案,这里是我在项目中使用的动作过滤器的代码。
它适用于 ASP Core RC2!
并在您的代码中使用它,例如
Extending Magpie's answer, here is the code for action filter which I use in my project.
It works with ASP Core RC2!
And use it in your code like
对于其他人来说,这里有一组不错的步骤。 http://forums.asp.net/t/1678976.aspx/1
不要忘记像我一样在 OnActionExecuting() 中手动添加密钥。
For anybody else looking, here is a decent set of steps. http://forums.asp.net/t/1678976.aspx/1
Don't forget to manually add your key in OnActionExecuting() like I did.