web-dev-qa-db-ja.com

CustomValidatorをValidationSummaryメッセージボックスと連携させるエレガントな方法

私は以前にこの問題に遭遇したことがありますが、完全に解決したことはありません。いくつかのバリデーターとCustomValidatorを含むフォームがあります。

<asp:Label ID="lblMemberNum" runat="server" Text="Membership #:" CssClass="LabelMedium"  ></asp:Label>
<asp:TextBox ID="txtMemberNum" runat="server" CssClass="TextBox" ></asp:TextBox>
<asp:RequiredFieldValidator ID="rfvMemberNum" SetFocusOnError="True" runat="server"
    ControlToValidate="txtMemberNum" ErrorMessage="[ Membership # ] is required"
    CssClass="ValidationMessage" Display="Dynamic" >*</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="revMemberNum"  Display="Dynamic" runat="server" 
    ControlToValidate="txtMemberNum" CssClass="ValidationMessage" 
    ErrorMessage="[ Membership # ] can only contain letters" 
    ValidationExpression="^([a-zA-Z\d]+)$" >*</asp:RegularExpressionValidator>
<asp:CustomValidator ID="cvMemberNum" runat="server" 
    CssClass="ValidationMessage" Display="Dynamic"
    ControlToValidate="txtMemberNum" ValidateEmptyText="false"
    OnServerValidate="cvMemberNum_Validate" 
    ErrorMessage="This membership number is already registered">*</asp:CustomValidator>

<asp:ValidationSummary ID="ValidationSummary1" runat="server" 
    CssClass="ValidationMessage" 
    ShowMessageBox="True" ShowSummary="False" />

およびサーバー側:

protected void cvMemberNum_Validate(object source, ServerValidateEventArgs args)
{
    try
    {
        args.IsValid  = (!CampaignRegistration.IsMemberRegistered(args.Value));
    }
    catch
    {
        args.IsValid = false;
    }
}

私の問題は、ValidationSummaryがCustomValidatorからのメッセージを表示しないことです。この質問はいくつかの場所で尋ねられましたが、私は満足のいく答えを見ていません。

19
Alfero Chingono

すべてのバリデーターとValidationSummaryでValidationGroupプロパティを使用してみてください。

編集:別の可能性はサーバー検証コードである可能性があります

_args.IsValid = (!CampaignRegistration.IsMemberRegistered(args.Value));
_

CampaignRegistration.IsMemberRegistered(args.Value)がfalseを返している場合、「!」それを真実にし、したがってそれを有効にしているのです。 「!」は消すべきだと思います。次のように:

_args.IsValid = CampaignRegistration.IsMemberRegistered(args.Value);
_

UPDATE:ValidationSummaryがカスタムバリデータメッセージをメッセージボックスに表示するには、 ClientValidationFunction コードが必要です。ポップアップなしで要約のみを表示する必要がある場合、これは必要ありません。

_<asp:CustomValidator ID="cvMemberNum" runat="server" 
    CssClass="ValidationMessage" Display="Dynamic"
    ControlToValidate="txtMemberNum" ValidateEmptyText="false"
    OnServerValidate="cvMemberNum_Validate"
    ClientValidationFunction = "ClientValidate"  
    ErrorMessage="This membership number is already registered">*</asp:CustomValidator>
   //JavaScript Code.
   function ClientValidate(source, args)
   {         
      args.IsValid = false; //you need to add validation logic here
   }
_

MORE:ClientSide検証を実行したくない場合は、このトリックを試してアラートを表示してください。 CustomValidatorServerValidateメソッドに次の変更を加えます。

_protected void cvMemberNum_Validate(object source, ServerValidateEventArgs args)
{
    bool isValid = true;
    try
    {
        isValid  = (!CampaignRegistration.IsMemberRegistered(args.Value));
    }
    catch
    {
        isValid = false;
    }
    args.IsValid = isValid;

    if(!isValid)
    {
       if(!Page.IsClientScriptBlockRegistered("CustomValidation")) 
         Page.RegisterClientScriptBlock("CustomValidation", "<script>alert('This membership number is already registered');</script>"); 

    }

}
_
10
Jose Basilio

ShowMessageBox オプションは完全にクライアント側であるため、 CustomValidatorClientValidationFunction を設定した場合にのみ評価されます。

アラートを作成するスクリプトを登録することで偽造することもできるため、サーバーの検証から戻ると、エラーメッセージが表示されます。これは、ServerValidateメソッドに登録するか( @ Jose Basilio ごと)、またはPreRenderイベント中に次のメソッドを呼び出して、ページ上のすべての無効なバリデーターにポップアップを登録できます。

    /// <summary>
    /// Registers a script to display error messages from server-side validation as the specified <see cref="UserControl"/> or <see cref="Page"/> loads from a postback.
    /// </summary>
    /// <remarks>
    /// Must be called in the PreRender if used to validate against the Text property of DNNTextEditor controls, otherwise Text will not be populated.
    /// Must set the ErrorMessage manually if using a resourcekey, otherwise the resourcekey will not have overridden the ErrorMessage property.
    /// </remarks>
    /// <param name="ctrl">The <see cref="UserControl"/> or <see cref="Page"/> which is being posted back.</param>
    /// <param name="validationGroup">The validation group against which to validate.</param>
    public static void RegisterServerValidationMessageScript(TemplateControl ctrl, string validationGroup)
    {
        if (ctrl != null && ctrl.Page.IsPostBack)
        {
            ctrl.Page.Validate(validationGroup);
            if (!ctrl.Page.IsValid)
            {
                StringBuilder errorMessage = new StringBuilder("<script language='javascript'>alert('");
                for (int i = 0; i < ctrl.Page.Validators.Count; i++)
                {
                    IValidator validator = ctrl.Page.Validators[i];
                    if (!validator.IsValid)
                    {
                        errorMessage.Append("- " + validator.ErrorMessage);
                        if (i < ctrl.Page.Validators.Count - 1)
                        {
                            errorMessage.Append(@"\r\n");
                        }
                    }
                }

                errorMessage.Append("');</script>");
                ctrl.Page.ClientScript.RegisterStartupScript(typeof(IValidator), "validationAlert", errorMessage.ToString(), false);
            }
        }
    }
7
bdukes

私は最近同じ問題を抱えています。 ServerValidateが検証の失敗を示したとき、ValidationSummaryはCustomValidatorからのErrorMessageを表示していませんでした。デフォルトでは(私の小さなリバースエンジニアリングが示したように)検証サマリーはポストバックでクライアント側にレンダリングされるため、ドキュメントのロード/非同期ポストバック完了時にすべてのバリデーターをチェックし、失敗した検証グループの検証サマリー作成をトリガーするスクリプトを追加しただけです。

$(document).ready(function () {
    var displayAlert = function () {
        if (typeof Page_Validators == 'undefined') return;

        var groups = [];
        for (i = 0; i < Page_Validators.length; i++)
            if (!Page_Validators[i].isvalid) {
                if (!groups[Page_Validators[i].validationGroup]) {
                    ValidationSummaryOnSubmit(Page_Validators[i].validationGroup);
                    groups[Page_Validators[i].validationGroup] = true;
                }
            }
    };

    displayAlert();

    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
                    function () {
                        displayAlert();
                    });
}
);

私のシナリオでは、親ページにバリデーター、更新パネル、検証の概要を含むネストされたユーザーコントロールがありました。

詳細はこちら

5
Maxim Saplin

これは私のために働いた:

<asp:CustomValidator runat="server" ID="cv" 
ClientValidationFunction="ValidateFunction"
ErrorMessage="Default error
message">*</asp:CustomValidator>

<script type="text/javascript">
function ValidateFunction(sender, args) 
{

var msg ='';
var formValid = true;

[various checks setting msg and formValid]

if (msg.length > 0) { sender.errormessage = msg; }
args.IsValid = formValid;

}
</script>
1
Morten71

あなたはプロパティを書くべきです

ValidationGroup="ValidationSummary1"

あなたの場合のすべてのバリデーターで。

また、ページに

AutoEventWireup="true"
1
Iralda Mitro

bdukeのRegisterServerValidationMessageScriptは「偽造」していますが、そうではありません。それは本当に問題を修正します。すべてのユーティリティ名前空間には、この関数がどこかに必要です。

1
Super Dave

Javascriptが無効になっていて、ValidationSummaryerrorMessageCustomValidatorプロパティが表示されない場合の回避策を見つけました。上記のように、スクリプトまたはアラートの挿入が機能しないため、これは必須です。

新しいValidatorコントロールを追加し、それをCustomValidatorProxyと呼び、そのControlToValidateプロパティをフォーム上のコントロールのいずれかに設定してEnableClientScript=false

ServerValidateイベントハンドラー内でカスタム検証を実行し、検証が失敗した場合は、IsValidおよびCustomValidatorCustomValidatorProxyプロパティをfalseに設定し、同様に両方のErrorMessageプロパティを設定します。

ServerValidateの検証に合格した場合は、CustomValidatorProxyのIsValidプロパティがtrueに設定されていることを確認してください。

CustomValidatorProxyがページのCustomValidatorValidatorCollectionの前にある場合、ServerValidateハンドラーはIsValidCustomValidatorProxy値とControlToValidateErrorMessage値とCustomValidatorを__VARI_から検証した場合に返すValidationSummaryプロパティ値をオーバーライドします。

1
user487779