5

ValidationProperty我有一个实现该属性的 ASP.NET 用户控件。此属性成功地使我可以将 aRequiredFieldValidator用于我的自定义控件,但是在验证时它会导致完整的回发,而不是使用基于客户端 javascript 的验证。

有没有办法在不使用自定义验证器的情况下防止这种情况并启用客户端验证?

这就是我的 UserControl 的样子。

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ucBooleanRadio.ascx.cs" Inherits="MyCompany.Web.UserControls.ucBooleanRadio" %>

<div class="BooleanRadio">
    <input runat="server" id="radTrue" type="radio" name="BooleanRadio" value="True" /> Yes
    <input runat="server" id="radFalse" type="radio" name="BooleanRadio" value="False" /> No
</div>

[ValidationProperty("Checked")]
public partial class ucBooleanRadio : System.Web.UI.UserControl
{
    public Nullable<bool> Checked
    {
        get
        {
            if (radTrue.Checked || radFalse.Checked)
                return radTrue.Checked;
            else
                return null;
        }
        set
        {
            radTrue.Checked = value != null ? value.Value : false;
            radFalse.Checked = value != null ? !value.Value : false;                    
        }
    }
}

这就是它的使用方式

<uc1:ucBooleanRadio ID="ucAgree" runat="server" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator6" runat="server" CssClass="Validator" Display="Dynamic" ControlToValidate="ucAgree" InitialValue="" ErrorMessage="You must agree to continue."></asp:RequiredFieldValidator>

Page.Validate();
if (Page.IsValid)
{
    //Do stuff
}
4

4 回答 4

1

好的,所以在深入研究了 ASP.NET 字段验证器的体系结构和上面海报的一些指导之后,我终于找到了解决方案。

基本上上面的答案是正确的,除非有一些变化。

首先,为隐藏文本设置的 id 不应在Name字段中,而应在ID字段中。Page.UniqueID此外,在 Hidden 字段中填充的 ID不应该是Page.ClientID相关 UserControl 的 ID。

这样做的原因是,当加载包含验证器的页面时,ASP.NET 框架会调用以下函数。

function ValidatorHookupControlID(controlID, val) {
    if (typeof (controlID) != "string") {
        return;
    }
    var ctrl = document.getElementById(controlID); //NOTE THIS LINE
    if ((typeof (ctrl) != "undefined") && (ctrl != null)) {
        ValidatorHookupControl(ctrl, val);
    }
    else {
        val.isvalid = true;
        val.enabled = false;
    }
}

框架试图做的是检索一个与所需字段验证器(实际上是 )中设置ID的属性相同的控件。然后,它在其验证功能(无论是RequiredField、Compare、Regex 等)中使用此控件。如果它找到这样的控件,它会启用验证器并针对其值执行验证,如果没有,它只是将验证器设置为禁用。ControlToValidatePage.ClientID

最后我的代码看起来像这样。

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ucBooleanRadio.ascx.cs" Inherits="MyCompany.Web.UserControls.ucBooleanRadio" %>

<input id="<% =this.ClientID %>" type="hidden" value="" />
<asp:RadioButton runat="server" ID="radTrue" Text="Yes" GroupName="radio" />
<asp:RadioButton runat="server" ID="radFalse" Text="No" GroupName="radio" />    

<script language="javascript" type="text/javascript">
    $(function (e) {
        $("#<% =radTrue.ClientID %>").click(function (e) {
            $("#<% =this.ClientID %>").val("true");
        });
        $("#<% =radFalse.ClientID %>").click(function (e) {
            $("#<% =this.ClientID %>").val("false");
        });
    });
</script>

并且后面的代码保持不变。希望这可以解释遇到相同问题的任何人所发生的事情的一些奥秘。

于 2012-06-27T03:23:39.740 回答
1

对于简单的客户端验证,应该有一个具有相应名称的输入元素,该元素的值将被验证。在您的情况下如何完成的示例:

<div class="BooleanRadio">
    <% radTrue.Attributes["onclick"] = "document.getElementsByName('" + UniqueID + "')[0].value='+'"; %>
    <input runat="server" id="radTrue" type="radio" name="BooleanRadio" value="True" /> Yes
    <% radFalse.Attributes["onclick"] = "document.getElementsByName('" + UniqueID + "')[0].value='-'"; %>
    <input runat="server" id="radFalse" type="radio" name="BooleanRadio" value="False" /> No
    <input name="<%= UniqueID %>" type="hidden" value="<%= radTrue.Checked? "+" : radFalse.Checked? "-" : "" %>" />
</div>
于 2012-06-21T05:56:15.850 回答
1

事实证明,ASP.NET 并不关心元素标记。
我刚刚查看了验证代码并发现了这个

function ValidatorGetValue(id) {
    var control;
    control = document.getElementById(id);
    if (typeof(control.value) == "string") {
        return control.value;
    }
    return ValidatorGetValueRecursive(control);
}

所以

<div class="BooleanRadio" id="<%= ClientID %>" value="<%= radTrue.Checked? "true" : radFalse.Checked? "false" : "" %>">
    <% radTrue.Attributes["onclick"] = "document.getElementById('" + ClientID + "').value='true'"; %>
    <% radFalse.Attributes["onclick"] = "document.getElementById('" + ClientID + "').value='false'"; %>
    <input runat="server" id="radTrue" type="radio" name="BooleanRadio" value="True" /> Yes
    <input runat="server" id="radFalse" type="radio" name="BooleanRadio" value="False" /> No
</div>

确实:\有效

<div class="BooleanRadio" id="<%= ClientID %>">
    <input runat="server" id="radTrue" type="radio" name="BooleanRadio" value="True" /> Yes
    <input runat="server" id="radFalse" type="radio" name="BooleanRadio" value="False" /> No
</div>

并且有事件自动挂钩 - 已验证元素(带有 ClientID 的元素)及其子元素被连接以自动进行验证(查看 ValidatorHookupControl)。
这可能会导致:
1. 用户做了某事
2. 执行
了验证 3. 验证的值被更新(在验证之后!)
div 上有值的第一个例子就是这样。

于 2012-06-27T08:25:13.257 回答
0

马克西姆,我一直在研究类似的问题。

我发现您不需要 JavaScript,验证器将自动遍历控件以查找已设置的“值”。

您必须使用服务器端 RadioButtons 而不是 HTML

如果您使用的是 CompositeControls,那么它将自动工作

如果您使用的是 Web 用户控件(ascx 文件),它不会使用 ID 包装控件,因此您需要将以下代码添加到您的控件中。

<div id='<%=ClientID %>'>

   Your radio button controls here...

</div>

编辑:我刚刚上传了一些快速示例代码。希望这可以帮助! 示例代码

于 2013-01-08T10:05:38.260 回答