Question

texte de remplacement http://img3.imageshack.us/img3/1488/advancedsearch. png

Je construis une " recherche avancée " interface dans une application ASP.NET. Je n'ai pas besoin de SO pour écrire cette chose pour moi, mais je suis coincé sur un problème spécifique concernant les contrôles dynamiques et ViewState. Je voudrais savoir comment aborder cela. Voici ma situation:

Ingrédients:

  • Ensemble d'objets API utilisables représentant des entités, des champs et des recherches, qui permet de créer une recherche, de générer du code SQL et de renvoyer les résultats. Donc, tout est pris en charge.
  • ASP.NET 3.5

Fonctionnalités d'interface souhaitées:

(1) Lors du chargement initial de la page, l'interface obtient un objet de recherche préconfiguré avec un ensemble d'objets SearchCriterion. Il les lie dans un ensemble de commandes (voir l’image ci-dessus.)

  • Certains éléments de recherche sont plus simples, tels que:

    Champ (DropDownList) | Opérateur (DropDownList) | Valeur (Zone de texte)

  • Les contrôles de critères de recherche de certains types de champs ont des informations importantes stockées dans l'état d'affichage, telles que:

    Champ (DropDownList) | Opérateur (DropDownList) | Value (DropDownList) où le "Value" La liste déroulante est remplie par une requête de base de données.

  • Certains champs sont des recherches sur d'autres entités, ce qui crée une chaîne de sélecteurs de champs, telle que:

    Champ (DropDownList) Champ (DropDownList) | Opérateur (DropDownList) | Valeur

(2) L'utilisateur modifie la recherche par:

  • Ajout et suppression de critères de recherche en cliquant sur les boutons correspondants
  • Configuration des critères existants en modifiant le champ, l'opérateur ou la valeur. Les modifications apportées au champ ou à l'opérateur nécessiteront que le contrôle se reconfigure en modifiant les opérateurs disponibles, en modifiant la valeur "Valeur". contrôle d’entrée dans un type différent, ou ajout / suppression de DropDownLists dans la liste & Field; Fields " section si les champs de type recherche sont sélectionnés / désélectionnés.

(3) Enfin, l'utilisateur clique sur "Recherche". pour voir leurs résultats.

Le problème:

Comme vous le savez probablement déjà si vous répondez à cette question, les contrôles ajoutés dynamiquement à la page disparaissent lors de la publication. J'ai créé un UserControl qui manipule la collection de contrôles et accomplit parfaitement l'étape (1) ci-dessus, comme vous pouvez le voir dans l'image jointe. (Je ne suis évidemment pas préoccupé par le style à ce stade.)

Cependant, dans Postback, les contrôles sont tous partis et mon objet API de recherche est parti. Si je pouvais obtenir que la collection de contrôles générée dynamiquement soit simplement jouée dans ViewState, je pourrais examiner les contrôles lors de la publication, reconstruire l’objet Rechercher, puis gérer les événements de contrôle avec soin.

Solutions possibles

  • Je pouvais rendre l'objet de recherche sérialisable et le stocker dans l'état de visualisation. Ensuite, lors du chargement de la page, je pouvais le récupérer et reconstruire la collection de contrôles au moment du chargement de la page. Cependant, je ne suis pas sûr que cela fonctionne correctement avec les contrôles qui soulèvent des événements et ce qu'il advient de l'état d'affichage des listes déroulantes contenant des données de la base de données. Puis-je les récupérer? Il est fortement déconseillé pour moi de devoir interroger à nouveau la base de données à chaque publication.

  • Je pourrais développer un contrôle serveur personnalisé ( voir ce lien ) pour ce genre de chose ... mais c’est un nouveau sujet pour moi qui impliquerait un peu d’apprentissage. De plus, je ne suis pas tout à fait sûr si un contrôle de serveur personnalisé fonctionnerait mieux avec des collections de contrôles non fixes. Quelqu'un est au courant?

  • Je pensais pouvoir réaliser cela à l'aide de contrôles liés aux données - par exemple, je pourrais lier ma collection de critères à un répéteur qui possède une collection de contrôles fixe (peut-être masquer les contrôles "valeur" non utilisés , utilisez un répéteur interne pour les listes déroulantes "Champ". Toutes les informations resteraient alors dans ViewState ... non?

  • Toute nouvelle idée serait grandement appréciée.

merci pour votre aide. b.Fandango

Était-ce utile?

La solution

Cela fait environ un jour que je code, et j’ai fonctionné à merveille avec la troisième option que j’ai suggérée dans ma question: les contrôles de databound à l’ancienne école. En fait, j’ai seulement pensé à l’idée lorsque j’ai été obligé d’écrire la question en détail - cela ne vous arrive-t-il pas tout le temps?

Je mets SearchCriterionControl dans un asp: Repeater et le lie à ma collection d'objets. Pour le sélecteur de champs, j'ai placé asp: DropDownList dans un asp: Repeater imbriqué et j'ai lié le tableau Field à celui-ci. Tout fonctionne à merveille, conserve son état, nécessite en réalité très peu de code. Donc, je n'ai jamais eu à ajouter de manière dynamique des contrôles à la page, Dieu merci.

Merci pour vos suggestions, Ender, Matt et AndrewWinn.

Autres conseils

Comme personne d’autre n’a essayé de répondre à cette question pendant 2 heures, je vais me lancer dans l’épreuve avec une solution qui ne repose pas du tout sur viewstate (ni sur le modèle de publication ASP.NET).

Que se passe-t-il si vous avez saisi toutes les valeurs d'entrée avec jQuery et au lieu de faire un post-back, une publication sur la page (ou une nouvelle page de results.aspx)? Vous pouvez également rendre le tout asynchrone et faire une requête Ajax contre une méthode Web, recevoir les résultats et renseigner du côté client si nécessaire.

Malheureusement, vous devez reconstituer le type de contrôle utilisé pour structurer votre requête de recherche, car ces données ne seront pas transmises à l'état de visualisation. Mais j'imagine que vous alliez déjà devoir faire une sorte de traduction de vos données d'entrée dans un formulaire de requête.

Lisez ici. pour plus d'informations sur l'utilisation de jQuery pour atteindre une méthode de page ASP.NET. Rappelez-vous - les méthodes de page doivent être statiques (c'est un oubli facile).

Je ne suis pas sûr de savoir ce que vous faites côté serveur pour construire votre requête - mais je recommanderais fortement de recommander LINQ. J'ai effectué une "recherche avancée" similaire. fonctionnait auparavant et après quelques tentatives différentes, il a été constaté que LINQ était un outil formidable pour résoudre ce problème, que je frappe SQL avec LINQtoSQL ou que je frappe simplement une collection d’objets en mémoire.

Cela a si bien fonctionné car 1) LINQ est une exécution différée et 2) une requête LINQ renvoie un autre objet interrogeable. L’implication ici est que vous pouvez chaîner vos requêtes LINQ ensemble lorsque vous les construisez à partir de votre entrée, au lieu de devoir convertir une seule clause massive en SQL ou l’arrière-magasin que vous utilisez (l’une de mes tentatives était de construire des clauses SQL avec des chaînes, mais toujours en transmettant les données d'entrée via SQLParameters pour la protection contre l'injection SQL - c'était compliqué lorsque LINQ a été fabriqué à la main, il était donc plus facile de comprendre et de mettre en œuvre des ordres de grandeur.

Par exemple:

List<string> data; // or perhaps your a DB Context for LINQtoSQL?

var query = data.Where(item => item.contains("foo"));

if( {user supplies length search option} )
    query = query.Where(item => item.Length < 5);

// etc, etc.

// LINQ doesn't do anything until the query is iterated, at which point
// it will construct the SQL statement without you worrying about details or parameter binding
foreach(string value in query)
    ; // do something with the results

En raison de l'exécution différée et du type de résultat pouvant être interrogé, vous pouvez concaténer des requêtes LINQ avec cette expression toute la journée et la laisser s'occuper des détails de la mise en œuvre (telle que la conversion en une requête SQL) au moment de l'exécution.

Je ne peux pas vous donner les étapes exactes que vous devrez faire, mais je suggère vivement de regarder dans le cycle de vie d'une page asp.net. J'ai créé un contrôle utilisateur en tant que DLL une fois. J'ai dû capturer les données de publication à des étapes spécifiques du cycle de vie, puis recréer et relier les données à d'autres étapes. De plus, les pensées comme viewstate ne sont disponibles qu’à certains moments. Je sais que je devais remplacer On_init, On_prerender et d'autres méthodes.

Désolé de ne pas pouvoir vous aider davantage, mais je n’ai pas le code avec moi (c’est avec un ancien employeur). J'espère que cela aide.

Si vous ajoutez des contrôles à l’arborescence de contrôles de manière dynamique, vous devez également les ajouter sur postpack. Appelez simplement la méthode qui construit le contrôle sur Page_Load ou Page_Init et les contrôles doivent rester sur la page à la publication.

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