Pregunta

texto alternativo http://img3.imageshack.us/img3/1488/advancedsearch. png

Estoy creando una " Búsqueda avanzada " interfaz en una aplicación ASP.NET. No necesito SO para escribir esto para mí, pero estoy atascado en un problema específico relacionado con los controles dinámicos y ViewState. Me gustaría alguna dirección sobre cómo abordar esto. Aquí está mi situación:

Ingredientes:

  • Un conjunto útil de objetos API que representan entidades, campos y búsquedas, que controla la construcción de una búsqueda, la generación de SQL y la devolución de los resultados. Así que todo está cuidado.
  • ASP.NET 3.5

Funcionalidad de interfaz deseada:

(1) En la carga de la página inicial, la interfaz obtiene un objeto de búsqueda preconfigurado con un conjunto de objetos SearchCriterion. Los une en un conjunto de controles (ver imagen arriba).

  • Algunos elementos de búsqueda son más simples, como:

    Campo (DropDownList) | Operador (DropDownList) | Valor (TextBox)

  • Los controles de criterios de búsqueda para algunos tipos de campos tienen información importante almacenada en viewstate, como:

    Campo (DropDownList) | Operador (DropDownList) | Valor (DropDownList) donde el " Valor " La lista desplegable se rellena con una consulta de base de datos.

  • Algunos campos son búsquedas de otras Entidades, lo que provoca una cadena de selectores de campo, como:

    Campo

    (DropDownList) Campo (DropDownList) | Operador (DropDownList) | Valor

(2) El usuario modifica la búsqueda mediante:

  • Agregar y eliminar criterios de búsqueda haciendo clic en los botones respectivos
  • Configuración de los criterios existentes cambiando el campo, el operador o el valor. Los cambios en Campo u Operador requerirán que el control se reconfigure a sí mismo cambiando los operadores disponibles, cambiando el " Valor " ingrese el control a un tipo diferente, o agregue / eliminando DropDownLists de los " Campos " sección si los campos de tipo de búsqueda están seleccionados / no seleccionados.

(3) Finalmente, el usuario pulsa " Buscar " para ver sus resultados.

El problema:

Como probablemente ya sepa si está respondiendo esta pregunta, los controles agregados dinámicamente a la página desaparecerán en la devolución de datos. He creado un UserControl que manipula la colección de control y cumple perfectamente el paso (1) anterior como se puede ver en la imagen adjunta. (No me preocupa el estilo en este punto, obviamente).

Sin embargo, en Devolución, todos los controles se han ido y mi objeto de la API de búsqueda se ha ido. Si pudiera obtener la colección de control generada dinámicamente para jugar bien y quedarse en ViewState, podría examinar los controles en la devolución de datos, reconstruir el objeto de búsqueda y luego manejar los eventos de control de forma ordenada.

Posibles soluciones

  • Podría hacer que el objeto de búsqueda se pueda serializar y almacenarlo en viewstate. Luego, en la carga de la página, podría agarrarlo y reconstruir la colección de control en el tiempo de carga de la página. Sin embargo, no estoy seguro de si esto funcionaría bien con los controles que generan eventos, y qué sucede con el estado de visualización de las listas desplegables que contienen datos de la base de datos. ¿Puedo recuperarlo? Es altamente indeseable para mí tener que volver a consultar la base de datos en cada devolución de datos.

  • Podría desarrollar un control de servidor personalizado ( ver este enlace ) para este tipo de cosas ... pero ese es un tema nuevo para mí e implicaría algo de aprendizaje, además, no estoy totalmente seguro de que un control de servidor personalizado funcione mejor con colecciones de control no fijas. ¿Alguien sabe sobre eso?

  • Estaba pensando que podría lograr esto usando controles de base de datos; por ejemplo, podría vincular mi colección de criterios a un repetidor que tenga una colección de control fija (tal vez ocultar el valor no usado " control " controles , use un repetidor interno para las "listas desplegables Campo". Entonces toda la información se quedaría en ViewState ... ¿verdad?

  • Cualquier nueva idea sería muy apreciada.

gracias por tu ayuda. b.Fandango

¿Fue útil?

Solución

He estado programando durante aproximadamente un día y conseguí que funcionara a la perfección con la tercera opción que sugerí en mi pregunta: los controles de datos de la vieja escuela. En realidad, solo pensé en la idea cuando me vi obligado a escribir la pregunta en detalle, ¿no te pasa eso todo el tiempo?

Pongo mi SearchCriterionControl en un asp: Repeater y lo vinculo a mi colección de objetos. Para el Selector de campo puse un asp: DropDownList dentro de un asp anidado: Repeater y enlazé la matriz de Field a eso. Todo funciona a la perfección, mantiene el estado, en realidad requiere muy poco código. Así que nunca tuve que agregar controles dinámicamente a la página, gracias a Dios.

Gracias por tus sugerencias, Ender, Matt y andrewWinn.

Otros consejos

Como nadie más ha intentado esto durante 2 horas, voy a lanzar mi sombrero al ring con una solución que no se basa en el estado de visualización (o en el modelo de devoluciones de ASP.NET).

¿Qué pasaría si capturara todos los valores de entrada con jQuery y en lugar de hacer un post-back hiciera una publicación en la página (o una nueva página de resultados.aspx)? O, ¿podría hacer todo lo asíncrono y hacer una solicitud Ajax en contra de un método web, recibir los resultados y completar el lado del cliente según sea necesario?

Lo desafortunado aquí es que debe reconstruir qué tipo de controles se usaron para calcular la construcción de su consulta de búsqueda ya que los datos no se pasarán con el estado de visualización. Pero imagino que de todos modos ya tendrías que hacer algún tipo de traducción de tus datos de entrada a un formulario de consulta.

Lea aquí para obtener más información sobre el uso de jQuery para golpear un método de página ASP.NET. Recuerde: los métodos de la página deben ser estáticos (es una supervisión fácil).

No estoy seguro de lo que está haciendo en el lado del servidor para construir su consulta, pero altamente recomiendo LINQ. Hice una " Búsqueda avanzada " " funcionó anteriormente, y después de varios intentos diferentes, descubrí que LINQ era una herramienta maravillosa para este problema, independientemente de si estaba golpeando SQL con LINQtoSQL o simplemente golpeando una colección de objetos en memoria.

Esto funcionó muy bien porque 1) LINQ es ejecución diferida y 2) Una consulta LINQ devuelve otro objeto consultable. La implicación aquí es que puede encadenar sus consultas LINQ juntas a medida que las construye desde su entrada, en lugar de tener que hacer una sola traducción masiva de cláusulas a SQL o cualquier almacén de respaldo que esté utilizando (uno de mis intentos fue construir cláusulas SQL con cadenas, pero aún pasando datos de entrada a través de SQLParameters para la protección de inyección SQL, era complicado y complicado cuando LINQ hecho a mano era órdenes de magnitud más fáciles de entender e implementar).

Por ejemplo:

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

Debido a la ejecución diferida y al tipo de retorno consultable, puede concatenar las consultas LINQ a esta expresión durante todo el día y dejar que se preocupe por los detalles de la implementación (como la conversión a una consulta SQL) en el momento de la ejecución.

No puedo proporcionarle los pasos exactos que deberá seguir, pero le recomiendo encarecidamente que examine el ciclo de vida de la página asp.net. Creé un control de usuario como DLL una vez. Tuve que capturar datos de devolución de datos en pasos específicos del ciclo de vida y volver a crear y volver a vincular los datos en otros pasos. Además, thinkgs like viewstate solo está disponible en ciertos puntos también. Sé que tuve que anular On_init, On_prerender y algunos otros métodos.

Lo siento, no podría ser de más ayuda, pero no tengo el código conmigo (es con un antiguo empleador). Espero que esto ayude.

Si está agregando controles al árbol de controles dinámicamente, también debe agregarlos en el paquete postal. Simplemente llame al método que construye el control en Page_Load o Page_Init y los controles deben permanecer en la página en la devolución de datos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top