web-dev-qa-db-ja.com

asp:RequiredFieldValidatorは非表示フィールドを検証しません

ASP.NETバリデーターは非表示フィールドを検証しないようです。次のようなメッセージが表示されます。

'hiddenFieldValidator'のControlToValidateプロパティによって参照されるコントロール 'hiddenField'は検証できません。

私のページには<asp:HiddenField>があり、クライアント側に何らかの値が入力されています。これはサーバーに一度存在する必要があるので、RequiredFieldValidatorを追加しました。

そしてそれは機能しません!

私が見ているように、回避策として、次のことができます。

1。カスタムバリデーターを使用し、それを非表示フィールドに関連付けずに、OnServerValidateでメソッドを呼び出すだけです。

2。 CSSスタイル<asp:TextBox>display:noneを使用すると、機能するはずです。

しかし、私はここで何かを見逃していないことを確認したいと思います。他のテキストフィールドと同じ方法で非表示フィールドを検証することは可能ですか? O多分3番目のよりエレガントなオプションですか?

TIA!

22
meme

表示される例外メッセージが示すように、HiddenFieldコントロールは標準の検証コントロールの対象にはならないようです。 CustomValidatorの回避策を使用します。

5

@Peterの答えは私に考えさせました、ControlPropertiesValidは実際に何をチェックしますか?

MSDNトピック を見ると、とりわけValidationPropertyAttribute ..うーん、つまりHiddenFieldから派生し、ValidationPropertyAttributeValueに設定して新しいクラスを装飾すると(私の目的では)、 'すべてがうまくいく」。そして、それはありません。

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

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

使用法-コントロールを含むアセンブリを必ず登録してください。

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

そして、Page/UserControlコンテンツ内:

<sw:HiddenField2 ID="hidSomeImportantID" runat="server" />

すべてのバリデーターはこれで動作します。追加の利点は、(私のように)カスタム検証関数を使用している場合、HiddenField2.Valueフィールドに含まれているためargs.Valueを簡単に評価できることです(サーバー側ではこれはServerValidateEventArgsです)。

36
Scotty.NET

残念ながら、RequiredFieldValidator OR CustomValidatorをそのまま使用して検証する信頼できる方法が見つからなかったため、私が思いついた回避策は次のとおりです。ControlToValidateプロパティを空のままにすると、大声で叫びます。以下のようなカスタムコントロールを作成するだけです。

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

プロパティの有効なチェックをオーバーライドして常にtrueを返すようにすることで、HiddenFieldを使用していることを気にせず、値を引き出して問題なく検証します。

5
Peter

これは、Scotty.NETによるソリューションへの応答です。返信するのに十分な評判がありません。

Scotty.NETに+1!

.NETやコンパイルなどについて十分に知らない私たちにとって、これは他の誰かのための彼の答えの使用を単純化するのに役立つかもしれません。

Visual Web Developer 2010Expressを使用するWebサイトでそれを利用したかったのです。

1)派生したHiddenField2を/ App_CodeにHiddenField2.csとして保存しましたが、1つ変更しました-> namespace Controls

2)次に、コントロールを登録するには:

a)ページ上で<%@ Register Assembly="App_Code" Namespace="Controls" TagPrefix="local" %>

b)web.configで、system.web>ページ>コントロール内で、<add tagPrefix="local" namespace="Controls" Assembly="App_Code" />

3)そして、もちろん、最後に、それを<local:HiddenField2 ...>と呼びます。

ファンキーなコードカラーリングになります。それを処理するために名前空間を改善するのはおそらくかなり簡単です。私の地元の環境で私にとって素晴らしい働きをします。ライブサーバーで問題が発生しないかどうかはわかりません。

追加の参照: Webサイトプロジェクトでasp.netコントロールを拡張する

4
GG2

@Andersのソリューションを拡張するには、CustomValidatorアプローチを使用して、最初にコントロールを見つけてキャストし、次にそのHiddenFieldを使用してPage.Request.Form[]で値を検索することにより、標準のUniqueIDコントロールの値を非常に簡単に取得できます。


例1:比較バリデーターの改善

この例は、実装に対してもう少しローカルな場合があります。以下は、HiddenFieldコントロールの検証のサポートを追加するための、CompareValidator.EvaluateIsValid()メソッド呼び出しの改良版です。この手法は、カスタムコントロールでHiddenFieldをラップする代わりに、任意のバリデーターに適用できますが、ControlPropertiesValidメソッドもオーバーライドして、HiddenFieldの存在下でtrueを認識して返す必要があることに注意してください。

...

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);
}

...    


例2:カスタム動的バリデーター

この例は、最初の例よりも少し複雑です。ページ上の別のコントロールの値に基づいて有効または無効にされるカスタム動的バリデーターを定期的に使用します(たとえば、このボックスがチェックされている場合はこのテキストボックスが必要です。それ以外の場合は検証する必要はありません)。そのようなバリデーターの1つは、組み込みのDynamicRequiredFieldValidatorを継承する私のRequiredFieldValidatorです。動的バリデーターには、バリデーターをオンにするかどうかを決定するために使用される2つのカスタム属性ControlThatEnablesControlValueThatEnablesがあります。以下は、バリデーターを有効にするかどうかを決定するメソッドのスニペットですが、上記のように、カスタムコントロールでラップすることなく、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;
    }
}

...


最終的な考え

実装の決定は、最終的には開発者としてのあなた次第ですが、私の好みは、カスタムコントロールでHiddenFieldsTextBoxesDropDownListsなどをラップするのではなく、カスタムコントロールで既存のバリデーターをラップすることです。このソリューションを好む主な理由は2つあります。(1)バリデーターのラップはValidationPropertyを追加するよりも数分しかかかりませんが、.NETバリデーターをさらに改善するための柔軟性と機会が大幅に向上します。 FindControl呼び出しを、現在のNamingContainer(デフォルト)で目的のコントロールIDを検索するカスタムメソッドにポイントし、コントロールが見つからない場合は、検索を外側のPageまたはNamingContainerの親に拡張できます。 (2)IMHOは、検証を改善しようとしている場合、検証を改善しようとしている場合はよりクリーンであり、逆に、WebControlを改善しようとしている場合は、WebControlを改善しようとしている場合はよりクリーンです。

私は@Scottyのソリューションを完全に尊重しており、それが唯一の変更である場合、彼のソリューションによってこれより5分多く節約できることを最初に認めます。ただし、私見では、長期的には@Andersの方が適している可能性があります。

4
Zachary Kniebel

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!" />
0
fubo