Les éléments ListBox réarrangés avec JavaScript provoquant une erreur de validation d'événement sur la publication

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

Question

J'ai créé un contrôle d’élément d’échange d’éléments comprenant deux zones de liste et des boutons qui me permettent d’échanger des éléments entre les deux listes. La permutation est faite en javascript. Je déplace également les éléments de haut en bas de la liste. Fondamentalement, lorsque je déplace les éléments dans la liste à droite, je stocke les données des éléments (GUID) dans un champ masqué. En postback, je lis simplement les GUID du champ. Tout fonctionne très bien, mais à la publication, je reçois l’exception suivante:

  

Argument de publication ou de rappel non valide. La validation d'événement est activée à l'aide de la configuration ou & Lt;% @ Page EnableEventValidation = & Quot; true & Quot; % > dans une page. Pour des raisons de sécurité, cette fonctionnalité vérifie que les arguments des événements de publication ou de rappel proviennent du contrôle serveur qui les a restitués à l'origine. Si les données sont valides et attendues, utilisez la méthode ClientScriptManager.RegisterForEventValidation afin d’enregistrer les données de publication ou de rappel pour validation.

J'ai préparé une application de test. Tout ce que vous avez à faire est de télécharger l'archive et d'exécuter le projet. Sur la page Web, sélectionnez les 3 éléments, appuyez sur Ajouter tout, puis déplacez le troisième élément vers le haut, puis appuyez sur & "Bouton &"; L'erreur apparaîtra. Désactiver la validation d'événement n'est en aucun cas acceptable. Quelqu'un peut-il m'aider, j'ai déjà passé deux jours sans trouver de solution.

APPLICATION D'ESSAI

Était-ce utile?

La solution 3

La première option entraînera des frais généraux considérables. J'ai défini mon propre contrôle Listbox personnalisé dérivé de la classe Listbox et effectué un remplacement des données loadpostback:

public class CustomListBox : ListBox
{
    protected override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
    {
        return true;
    }
}

L’utilisation de cette option au lieu de la zone de liste normale dans mon contrôle d’utilisateur a résolu le problème. Cependant, mon approche présente-t-elle des risques?

Autres conseils

Le problème est que l'état d'affichage enregistré de la liste et les données reçues sur publication ne correspondent pas. Le problème de validation d’événement n’est probablement que l’un des problèmes pouvant découler de cette approche. L'architecture des formulaires Web ne permet pas ce type d'utilisations et, très probablement, cette approche posera davantage de problèmes, même si vous réussissez à éviter le problème de validation des événements. Vous avez plusieurs alternatives:

1) Le plus simple est d'effectuer la logique de permutation sur le serveur au lieu d'utiliser javascript. De cette manière, l'état d'affichage sera préservé entre les publications et les frais généraux liés à plusieurs allers-retours vers le serveur pourraient ne pas être un problème.

2) Si plusieurs allers-retours au serveur posent un problème, écrivez un contrôle serveur qui gère son propre état d'affichage. C'est bien sûr une approche très engageante.

3) Une approche intermédiaire pourrait consister à utiliser deux listes HTML simples (il suffit d'écrire les balises HTML sans utiliser les contrôles asp.net) et de maintenir côté client à partir de javascript une liste d'identifiants dans un champ masqué. Sur post back, il suffit d'analyser le champ caché et d'extraire l'identifiant en ignorant les listes html.

J'irais avec 1 s'il n'y a pas d'argument SÉRIEUX contre.

Quelques options possibles:

  • Si possible, désactivez ViewState sur les deux listes. Sans ViewState, le serveur ne saura pas quelles étaient les valeurs d'origine et n'errera donc pas. Avec cette approche, vous devrez repeupler les listes (en raison de l'absence de ViewState) et devrez peut-être suivre la sélection manuellement - ou devrez remplir les listes pendant la phase OnInit.

  • Désactivez la validation de l'événement (si vous le pouvez)

  • Remplissez complètement les deux listes côté serveur et utilisez un script côté client (javascript) pour supprimer les entrées de ces deux listes selon vos besoins.

Par chance, avez-vous déjà essayé cela? Faites-le chaque fois que vous bloquez la liste de quelque façon que ce soit.

document.getElementById("listbox").selectedIndex = -1;

Il se plaint parce que l'élément sélectionné dans une liste n'était pas présent dans la liste lors de son rendu. Envisagez d'utiliser PageMethods via AJAX pour récupérer vos données dans votre formulaire au lieu de PostBack. Vous pouvez également utiliser des contrôles non saisis pour conserver les données, comme des listes non ordonnées dans lesquelles vous déplacez des éléments de liste. Vous pouvez placer les GUID dans des plages masquées à l'intérieur de l'élément de liste, où vous pourrez les obtenir si nécessaire.

Sinon, vous pouvez utiliser un HtmlSelect côté serveur à la place d'un ListBox pour contourner le problème de validation d'événement. Mieux encore, vous pourrez peut-être laisser une bonne partie de votre code-behind intact (la logique de la population de liste est identique à celle de ListBox).

<select runat="server" id="myList" multiple="true" />

Vous pouvez remplacer l'événement de rendu pour enregistrer tous les éléments de zone de liste possibles avec les deux zones de liste. Ainsi, quels que soient les éléments déplacés, la validation les attend.

protected override void Render(HtmlTextWriter writer)
{
  foreach (DictionaryEntry entry in ColumnConfig) {          
    Page.ClientScript.RegisterForEventValidation(lstbxColumnsToExport.UniqueID,(string)entry.Key);
    Page.ClientScript.RegisterForEventValidation(lstbxNonExportColumns.UniqueID,(string)entry.Key);
  }
  base.Render(writer);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top