我正在尝试使用 FluentValidation 验证 ReCaptcha,但我遇到了一些问题。即使 ReCaptcha.Validate 返回 true,ModelState 也是无效的。为了验证 ReCaptcha,我在视图模型中添加了一个字段。在检查 ModelState 是否有效之前,我将 ReCaptcha 字段设置为从 ReCaptcha.Validate 返回的任何内容。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(Over18Model model)
{
model.ReCaptcha = Microsoft.Web.Helpers.ReCaptcha.Validate("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
if (ModelState.IsValid)
{
var table = new Prospect();
dynamic o = new ExpandoObject();
{
o.FirstName = model.FirstName;
o.LastName = model.LastName;
o.Email = model.Email;
}
table.Save(o);
return RedirectToAction("ThankYou", "Public");
}
ModelState.AddModelError(string.Empty, "Errors: " + string.Join(" ; ", ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage)));
return View(model);
}
[Validator(typeof(Over18ModelValidator))]
public class Over18Model
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public bool ReCaptcha { get; set; }
}
public class Over18ModelValidator : AbstractValidator<Over18Model>
{
public Over18ModelValidator()
{
RuleFor(x => x.FirstName).NotEmpty().WithMessage("First Name is Required");
RuleFor(x => x.LastName).NotEmpty().WithMessage("Last Name is Required");
RuleFor(x => x.Email).NotEmpty().WithMessage("Email is Required");
RuleFor(x => x.Email).EmailAddress().WithMessage("Invalid Email");
RuleFor(x => x.ReCaptcha).Equal(true).WithMessage("ReCaptcha error");
}
}
Razor 代码如下所示...
<div class="signUpOver18">
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Form.TextBox(name: "FirstName", value: @Model.FirstName, labelText: "First Name:", containerClass: "fname", txtfldClass: "standard names", maxLength: 50)
@Form.TextBox(name: "LastName", value: @Model.LastName, labelText: "Last Name:", containerClass: "lname", txtfldClass: "standard names", maxLength: 100)
</div>
@Form.Submit(value: "Enter The Sweepstakes", myClass: "btnSubmit")
<div class="recaptchaHolder">
@ReCaptcha.GetHtml(theme: "red", publicKey: "XXX-XXXX_XXXX-XX_")
</div>
@Html.ValidationSummary(true)
}
</div>