Un moyen élégant de faire fonctionner CustomValidator avec la boîte de message ValidationSummary

StackOverflow https://stackoverflow.com/questions/811734

Question

J'ai déjà rencontré ce problème mais je ne l'ai jamais vraiment résolu. J'ai un formulaire avec plusieurs validateurs et aussi un 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]+)
protected void cvMemberNum_Validate(object source, ServerValidateEventArgs args)
{
    try
    {
        args.IsValid  = (!CampaignRegistration.IsMemberRegistered(args.Value));
    }
    catch
    {
        args.IsValid = false;
    }
}
quot; >*</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" />

et côté serveur:

<*>

Mon problème est le suivant: le ValidationSummary n’affiche jamais le message de CustomValidator. Cette question a été posée à plusieurs endroits, mais je n’ai pas obtenu de réponse satisfaisante.

Était-ce utile?

La solution

Essayez d'utiliser une propriété ValidationGroup sur tous vos validateurs et le ValidationSummary.

MODIFIER: le code de validation du serveur pourrait également être proposé

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

si CampaignRegistration.IsMemberRegistered (args.Value) renvoie la valeur false, "!!". c'est le rendre vrai et donc le rendre valide. Je pense que vous devriez vous débarrasser du "!!" comme suit:

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

UPDATE: Pour que ValidationSummary puisse afficher votre message de validation personnalisé dans une boîte à messages, vous devez disposer d'un ClientValidationFunction Code. Si vous ne souhaitez afficher que le résumé sans fenêtre contextuelle, cela n'est pas nécessaire.

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

PLUS: si vous ne souhaitez pas effectuer la validation ClientSide, essayez cette astuce pour afficher l'alerte. Apportez cette modification à votre méthode CustomValidator ServerValidate:

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

    }

}

Autres conseils

Le ShowMessageBox est entièrement côté client, elle sera donc évaluée uniquement si vous avez défini la ClientValidationFunction sur CustomValidator .

Vous pouvez également le simuler en enregistrant un script qui déclenche une alerte. Ainsi, lorsque vous revenez de la validation du serveur, le message d'erreur s'affiche. Cela peut être enregistré dans la méthode ServerValidate (selon @Jose Basilio ) ou vous pouvez appeler la méthode suivante lors de l'événement PreRender pour enregistrer une fenêtre contextuelle avec tous les validateurs non valides de la page:

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

J'ai récemment eu le même problème. ValidationSummary n'affichait pas le message ErrorMessage de CustomValidator lorsque ServerValidate a déclaré un échec de validation. Comme par défaut (comme mon petit calcul inverse l'a montré), le résumé de validation est rendu côté client lors de la publication. J'ai simplement ajouté un script qui vérifie tous les validateurs lors de l'achèvement de la publication du chargement / async du document et déclenche la création d'un résumé de validation pour les groupes de validation ayant échoué:

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

Dans mon scénario, j'avais imbriqué des contrôles utilisateur avec des validateurs, un panneau de mise à jour et un résumé de validation sur la page parente.

Plus de détails ici.

Vous devriez écrire une propriété

ValidationGroup = "ValidationSummary1"

à chaque validateur dans votre cas.

Vérifiez également si votre page contient

AutoEventWireup="true"

Cela a fonctionné pour moi:

<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>

RegisterServerValidationMessageScript de bduke est "simulé", mais ce n'est pas le cas. Cela corrige vraiment le problème. Tous les espaces de noms d’utilitaires ont besoin de cette fonction quelque part.

J'ai trouvé une solution de contournement lorsque javascript est désactivé et que le ValidationSummary n'affiche pas la propriété errorMessage du CustomValidator . Cela est nécessaire car un script d'injection ou des alertes, comme décrit ci-dessus, ne fonctionneront pas.

Ajouter un nouveau contrôle Validator, appelons-le CustomValidatorProxy , définissez sa propriété ControlToValidate sur l'un des contrôles du formulaire et EnableClientScript = false .

Dans le gestionnaire d'événements ServerValidate , effectuez votre validation personnalisée. Si la validation échoue, définissez la propriété IsValid de CustomValidator et CustomValidatorProxy sur false et définit de manière similaire les deux propriétés ErrorMessage .

Si la validation dans ServerValidate est réussie, assurez-vous que la propriété IsValid de CustomValidatorProxy est définie sur true.

Si le CustomValidatorProxy est avant le CustomValidator dans le ValidatorCollection de la page, le gestionnaire ServerValidate remplacera le IsValid valeur de propriété que CustomValidatorProxy aurait renvoyé après avoir validé la valeur ControlToValidate et votre ErrorMessage de votre CustomValidator être affiché dans le résumé de validation .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top