asp:RequiredFieldValidator不验证隐藏字段

时间:2011-07-07 08:45:45

标签: c# asp.net validation webforms controls

ASP.NET验证程序似乎不验证隐藏字段。我收到这样的消息:

  

无法验证由“hiddenFieldValidator”的ControlToValidate属性引用的控件'hiddenField'。

我的页面中有一个<asp:HiddenField>,它在客户端填充了一些值。我需要在服务器上显示一次,因此我添加了RequiredFieldValidator

它不起作用!

我认为,作为一种解决方法,我可以:

1。使用自定义验证器,而不是将其绑定到隐藏字段,只需在OnServerValidate上调用方法;

2。使用带有CSS样式<asp:TextBox>的{​​{1}},它应该有效。

但我想确保我在这里没有遗漏一些东西。是否可以以与其他文本字段相同的方式验证隐藏字段? O可能是第三种,更优雅的选择?

TIA!

6 个答案:

答案 0 :(得分:36)

@Peter的回答让我思考,ControlPropertiesValid实际检查了什么?

查看MSDN topic除了其他内容ValidationPropertyAttribute之外的其他内容......嗯,如果我们只是从HiddenField派生并用{{1}装饰新类设置为ValidationPropertyAttribute(为了我的目的)然后'一切正常'。确实如此。

Value

用法 - 确保注册包含控件的程序集:

using System.Web.UI;
using System.Web.UI.WebControls;

namespace Partner.UserControls {
    [ValidationProperty("Value")]
    public class HiddenField2 : HiddenField {
    } // nothing else required other than ValidationProperty
}

在您的Page / UserControl内容中:

<%@ Register Assembly="MyApp" Namespace="MyApp.Controls" TagPrefix="sw" %>

所有验证器都适用于此。额外的好处是,如果您(像我一样)使用自定义验证功能,您可以轻松评估<sw:HiddenField2 ID="hidSomeImportantID" runat="server" /> ,因为它包含在HiddenField2.Value字段中(在服务器端,这是args.Value )。

答案 1 :(得分:5)

正如您所说的异常消息所示,似乎HiddenField控件无法直接通过标准验证控件进行定位。我会选择CustomValidator解决方法。

答案 2 :(得分:5)

以下是我提出的解决方法,因为遗憾的是我找不到任何可靠的方法来使用RequiredFieldValidator或CustomValidator开箱验证。如果将ControlToValidate属性保留为空,则会对您大喊大叫。您所要做的就是创建一个自定义控件,如下所示:

public class HiddenFieldValidator : RequiredFieldValidator
{
    protected override bool ControlPropertiesValid()
    {
        return true;
    }
}

通过覆盖属性有效检查以使其始终返回true,它不再关心您正在使用HiddenField,它将从中提取值并验证没有问题。

答案 3 :(得分:4)

这是对Scotty.NET解决方案的回应。我只是没有足够的声誉来回复。

给Scotty.NET +1!

对于我们这些对.NET和编译不够了解的人来说,这可能有助于简化他人对其他人的回答。

我想在使用Visual Web Developer 2010 Express的网站中使用它:

1)我将/ App_Code中的派生HiddenField2保存为HiddenField2.cs,只需更改一次 - &gt; namespace Controls

2)然后,注册控件:

a)在页面上<%@ Register Assembly="App_Code" Namespace="Controls" TagPrefix="local" %>

b)在web.config中,在system.web&gt;中;页面&gt;控件,<add tagPrefix="local" namespace="Controls" assembly="App_Code" />

3)最后,当然,请将其称为<local:HiddenField2 ...>

它确实可以实现时髦的代码着色。可能相当容易改进命名空间来处理它。在我当地的环境中为我精彩地工作;我不知道它在实时服务器上不会出现问题。

补充参考: extending asp.net control in the website project

答案 4 :(得分:4)

要使用CustomValidator方法扩展@Anders的解决方案,您可以通过首先找到控件,强制转换它,然后使用它{{{}}}来轻松获取标准HiddenField控件的值。 {1}}在UniqueID中查看其值。


示例1:改进比较验证器

此示例可能对您的实现更为本地化。以下是Page.Request.Form[]方法调用的改进版本,以便添加对验证CompareValidator.EvaluateIsValid()控件的支持。请注意,此技术可以应用于任何验证器,而不是将HiddenField包装在自定义控件中,但是HiddenField方法也应该被覆盖以识别并在{{存在时返回true] 1}}。

ControlPropertiesValid


示例2:自定义动态验证器

这个例子比第一个例子复杂一点。我经常使用根据页面上另一个控件的值启用或禁用的自定义动态验证器(例如,如果选中该框,则需要此文本框;否则无需验证)。一个这样的验证器是我的HiddenField,它继承自内置... private new string GetControlValidationValue(string id) { var control = this.NamingContainer.FindControl(id); if (control != null) { if (control is HiddenField) { return Page.Request.Form[((HiddenField)control).UniqueID]; } else { return base.GetControlValidationValue(id); } } } protected override bool EvaluateIsValid() { // removed 'base.' from the call to 'GetControlValidationValue' string controlValidationValue = GetControlValidationValue(base.ControlToValidate); if (controlValidationValue.Trim().Length == 0) { return true; } bool flag = (base.Type == ValidationDataType.Date) && !this.DetermineRenderUplevel(); if (flag && !base.IsInStandardDateFormat(controlValidationValue)) { controlValidationValue = base.ConvertToShortDateString(controlValidationValue); } bool cultureInvariantRightText = false; string date = string.Empty; if (this.ControlToCompare.Length > 0) { //same as above date = GetControlValidationValue(this.ControlToCompare); if (flag && !base.IsInStandardDateFormat(date)) { date = base.ConvertToShortDateString(date); } } else { date = this.ValueToCompare; cultureInvariantRightText = base.CultureInvariantValues; } return BaseCompareValidator.Compare(controlValidationValue, false, date, cultureInvariantRightText, this.Operator, base.Type); } ... 。动态验证程序有两个自定义属性DynamicRequiredFieldValidatorRequiredFieldValidator,用于决定是否应启用验证程序。以下是该方法的片段,用于确定是否应启用验证器,但请注意,如上所述,此相同技术可应用于验证ControlThatEnables,而无需将其包装在自定义控件中。

ControlValueThatEnables


最后的想法

实施决策最终取决于您,作为开发人员,但我的首选是将现有验证器包装在自定义控件中,而不是包装诸如HiddenField... var enablingControl = this.NamingContainer.FindControl(ControlThatEnables); if (enablingControl != null) { if (enablingControl is HiddenField) { var hfValue = Page.Request.Form[((HiddenField)enablingControl).UniqueID]; isValidatorEnabled = hfValue == ControlValueThatEnables; } } ... ,{{1}之类的内容自定义控件中的等等。我有两个主要原因来选择这个解决方案:(1)包装验证器只需要几分钟而不仅仅是添加HiddenFields,但是为进一步改进.NET验证提供了更大的灵活性和机会,例如:可以将TextBoxes调用指向某个自定义方法,该方法在当前DropDownLists(默认)中搜索所需的控件ID,然后将搜索范围扩展到外部ValidationProperty或{{1如果找不到控件,则为父级; (2)恕我直言,如果一个人试图改进验证,改进验证就更清晰了,相反,如果一个人试图改进FindControl,那么对NamingContainer进行改进就更清晰了。 }。

我完全尊重@ Scotty的解决方案,并且会首先承认,如果这是唯一的改变,那么他的解决方案将比你节省5分钟。然而,恕我直言,从长远来看,@安德斯可能是一个更好的选择。

答案 5 :(得分:0)

我选择CustomValidator客户端

<script type="text/javascript">
function myMethod(source, args) {
    args.IsValid = document.getElementById("<%= myValue.ClientID %>").value != '';
}
</script>

<asp:HiddenField ID="myValue" runat="server" />
<asp:CustomValidator runat="server" ClientValidationFunction="myMethod" 
                     ErrorMessage="Value missing!" />