我有一个包含登录控件的母版页,以便用户可以从任何页面登录/注销。但是,有几个内容页面需要 Recaptcha 控件。这会导致问题,因为当我尝试登录具有 Recaptcha 控件的页面时,系统希望我输入单词。我知道 Recaptcha 控件中缺少验证组,并且您不能在 ASP.NET 页面上拥有多个表单。有没有办法解决这个问题?我能想到的一种“hacky”方式是在“登录”事件中,检查页面是否有 Recaptcha 控件。如果存在,则禁用它,否则继续。但是,这似乎效率很低,尤其是当有很多页面并且大多数页面都没有 Recaptcha 控件时。
4 回答
此问题的解决方法如下:
- 将 ValidationGroup 设置为登录按钮。当单击 ValidationGroup 设置为非空的按钮时,reCAPTCHA 控件将不会验证。
- 在需要 reCAPTCHA 验证的页面上,将按钮的 ValidationGroup 值保持为非空(否则,登录字段也将被验证),但在子例程上手动调用 RecaptchaControl.Validate()。
你应该做的是:
<form runat="server"></form>
应该围绕您的整个页面内容,在您的情况下在母版页上,因为登录也在那里。
从这一点开始,您可以在派生自给定母版页的任何页面上放置一个 recaptcha 控件。您在任何地方都不需要另一个<form runat="server"></form>
标签。
您必须了解,recaptcha 控件既不绑定到html 表单提交按钮,也不绑定到任何其他特定按钮。每次页面回发时,recaptcha 都会设置Page.IsValid
标志。
遗憾的是,recaptcha 不遵循 ASP.NET 标准,它使用触发验证与验证组相结合。
因此,为了防止每次都验证 recaptcha,您必须设置:SkipRecaptcha = true
这会导致 recaptcha 无法验证。因此,现在涵盖了登录场景。当您想要实际使用刚刚设置SkipRecaptcha = false
并调用的 recaptcha 功能时Page.Validate()
。之后,您可以像以前一样继续使用Page.IsValid
.
一种更简洁、更好的方法是重写 recaptcha 控件以使用BaseValidator
该类。这将允许您在 recaptcha 控件上指定一个验证组,以及提交要通过 recaptcha 保护的输入的按钮。然后按下按钮将仅导致对指定验证组的验证。
此外,您必须为登录按钮指定验证组或设置CausesValidation = false
. 如果没有设置验证组并且按下按钮,所有验证组都会自动验证。
然而,这是相当先进的,所以即使是 recaptcha 的人也放弃了它,但源代码控制中仍然有一个旧版本。不能保证该版本仍然有效。让我们知道您是如何决定的。
我不是 100% 确定这是相关的,但我遇到了 ReCaptcha 控件在每次回发时触发的问题 - IsValid 属性逻辑有缺陷。我修复了这个特定问题:http ://code.google.com/p/recaptcha/issues/detail?id=56#c3
不幸的是,ReCaptcha 项目有些停滞不前,并且有一段时间没有修复它进入发行版。
我与母版页中的登录控件处于完全相同的位置,并且设置SkipRecaptcha=true;
对我不起作用。该页面仍未通过验证,并且我的 LoggingIn 事件从未在母版页中触发。
我见过无数的解决方法,包括更新支持稀少的 Recapta,但我决定只是有选择地从等式中删除它。
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostback && Request["__EVENTTARGET"] == "ctl00$Login1$loginbuttonID")
Page.Validators.Remove(recaptcha);
}