Estoy tratando de construir una "micro-aplicación web" muy, muy simple, que sospecho que será de interés para algunos desbordadores de pila si alguna vez lo consigo. Lo alojo en mi sitio C # en profundidad, que es ASP.NET 3.5 de vainilla (es decir, no MVC).
El flujo es muy simple:
- Si un usuario ingresa a la aplicación con una URL que no especifica todos los parámetros (o si alguno de ellos no es válido), solo quiero mostrar los controles de entrada del usuario. (Solo hay dos)
- Si un usuario introduce la aplicación con una URL que hace que todos los parámetros necesarios, quiero mostrar los resultados y los controles de entrada (para que puedan cambiar los parámetros)
Aquí están mis requisitos autoimpuestos (mezcla de diseño e implementación):
- Quiero que el envío use GET en lugar de POST, principalmente para que los usuarios puedan marcar la página fácilmente.
- Yo no quiero la URL para terminar parecer tonto después de la presentación, con trozos y piezas extrañas en él. Solo la URL principal y los parámetros reales, por favor.
- Idealmente, me gustaría evitar requerir JavaScript en absoluto. No hay una buena razón para ello en esta aplicación.
- Quiero poder acceder a los controles durante el tiempo de renderizado y establecer valores, etc. En particular, quiero poder establecer los valores predeterminados de los controles a los valores de parámetros pasados, si ASP.NET no puede hacer esto automáticamente para mí (dentro de las otras restricciones).
- Estoy feliz de hacer toda la validación de parámetros yo mismo, y no necesito mucho en cuanto a los eventos del lado del servidor. Es realmente simple configurar todo en la carga de la página en lugar de adjuntar eventos a botones, etc.
La mayor parte de esto está bien, pero no he encontrado ninguna forma de eliminar completamente el estado de vista y mantener el resto de la funcionalidad útil. Utilizando la publicación de esta publicación de blog , he logrado evitar obtener un valor real para el estado de vista, pero aún así termina como un parámetro en la URL, que se ve realmente feo.
Si lo convierto en un formulario HTML simple en lugar de un formulario ASP.NET (es decir, sacarlo runat="server"
), entonces no obtengo ningún estado de vista mágico, pero no puedo acceder a los controles mediante programación.
Yo podría hacer todo esto haciendo caso omiso de la mayoría de ASP.NET y la creación de un documento XML con LINQ to XML, y la implementación IHttpHandler
. Sin embargo, eso se siente un poco bajo.
Me doy cuenta de que mis problemas podrían resolverse relajando mis restricciones (por ejemplo, utilizando POST y sin importar el parámetro excedente) o utilizando ASP.NET MVC, pero ¿son realmente irrazonables mis requisitos?
¿Quizás ASP.NET simplemente no se reduce a este tipo de aplicación? Sin embargo, hay una alternativa muy probable: solo estoy siendo estúpido, y hay una manera perfectamente simple de hacerlo que simplemente no he encontrado.
¿Alguna idea, alguien? (Señales de cómo cayeron los poderosos, etc. Está bien, espero nunca haber afirmado ser un experto en ASP.NET, ya que la verdad es todo lo contrario ...)
Respuestas:
Esta solución le dará acceso programático a los controles en su totalidad, incluidos todos los atributos de los controles. Además, solo los valores del cuadro de texto aparecerán en la URL al enviarla, por lo que su URL de solicitud GET será más "significativa"
Luego, en su código subyacente, puede hacer todo lo que necesita en PageLoad
Si no desea un formulario que tenga
runat="server"
, entonces debe usar controles HTML. Es más fácil trabajar con usted para sus propósitos. Simplemente use etiquetas HTML normalesrunat="server"
y póngales una identificación. Luego puede acceder a ellos mediante programación y codificar sin aViewState
.El único inconveniente es que no tendrá acceso a muchos de los controles de servidor ASP.NET "útiles" como
GridView
s. Incluí unRepeater
en mi ejemplo porque supongo que desea tener los campos en la misma página que los resultados y (que yo sepa) aRepeater
es el único control DataBound que se ejecutará sin unrunat="server"
atributo en la etiqueta Form.fuente
Definitivamente (en mi humilde opinión) está en el camino correcto al no usar runat = "server" en su etiqueta FORM. Sin embargo, esto solo significa que deberá extraer valores de Request.QueryString directamente, como en este ejemplo:
En la propia página .aspx:
y en el código subyacente:
El truco aquí es que estamos usando ASP.NET Literals dentro de los atributos value = "" de las entradas de texto, por lo que los cuadros de texto en sí no tienen que ejecutar runat = "server". Los resultados se envuelven dentro de un ASP: Panel, y la propiedad Visible establecida en la carga de la página depende de si desea mostrar los resultados o no.
fuente
De acuerdo, Jon, el problema del estado de vista primero:
No he comprobado si hay algún tipo de cambio de código interno desde 2.0, pero así es como manejé deshacerme del estado de vista hace unos años. En realidad, ese campo oculto está codificado dentro de HtmlForm, por lo que debe derivar el nuevo y pasar a su representación haciendo las llamadas usted mismo. Tenga en cuenta que también puede dejar __eventtarget y __eventtarget fuera si se apega a los controles de entrada antiguos simples (lo que supongo que le gustaría, ya que también ayuda a no requerir JS en el cliente):
Entonces obtienes esos 3 MethodInfo estáticos y los llamas omitiendo esa parte de viewstate;)
y aquí está el constructor de tipos de tu formulario:
Si respondo bien a su pregunta, tampoco desea utilizar POST como acción de sus formularios, así que así es como lo haría:
Supongo que esto es todo. Déjame saber como va.
EDITAR: Olvidé los métodos de visualización del estado de la página:
Entonces su Formulario personalizado: HtmlForm obtiene su nuevo resumen (o no) Página: System.Web.UI.Page: P
En este caso, sello los métodos porque no puedes sellar la Página (incluso si no es abstracta, Scott Guthrie lo envolverá en otro: P) pero puedes sellar tu Formulario.
fuente
¿Ha pensado no eliminar la POST sino más bien redirigir a una URL GET adecuada cuando se envía el formulario? Es decir, acepte GET y POST, pero en POST construya una solicitud GET y redirija a ella. Esto podría manejarse en la página o mediante un HttpModule si desea que sea independiente de la página. Creo que esto facilitaría mucho las cosas.
EDITAR: supongo que tiene EnableViewState = "false" establecido en la página.
fuente
Crearía un módulo HTTP que maneje el enrutamiento (similar a MVC pero no sofisticado, solo un par de
if
declaraciones) y lo entregaría aaspx
oashx
páginas.aspx
es preferible ya que es más fácil modificar la plantilla de página. Sin embargo, no lo usaríaWebControls
en elaspx
. JustoResponse.Write
.Por cierto, para simplificar las cosas, puede hacer la validación de parámetros en el módulo (ya que probablemente comparte código con enrutamiento) y guardarlo
HttpContext.Items
y luego renderizarlos en la página. Esto funcionará más o menos como el MVC sin todas las campanas y silbatos. Esto es lo que hice mucho antes de los días ASP.NET MVC.fuente
Realmente me complace abandonar por completo la clase de página y solo manejar cada solicitud con un gran caso de cambio basado en la URL. Cada "página" se convierte en una plantilla html y un objeto ac #. La clase de plantilla utiliza una expresión regular con un delegado de coincidencia que se compara con una colección de claves.
beneficios:
bummers:
Jon, ¿qué estamos haciendo en SO un sábado por la mañana :)?
fuente
Pensé que el asp: el control del repetidor era obsoleto.
El motor de plantillas ASP.NET es agradable, pero puede realizar fácilmente la repetición con un bucle for ...
ASP.NET Forms está bastante bien, hay un soporte decente de Visual Studio pero esto de runat = "server", eso está mal. ViewState to.
Le sugiero que eche un vistazo a lo que hace que ASP.NET MVC sea tan bueno, a quién se aleja del enfoque de formularios ASP.NET sin tirarlo por completo.
Incluso puede escribir su propio material de proveedor de compilación para compilar vistas personalizadas como NHaml. Creo que debería buscar aquí más control y simplemente confiar en el tiempo de ejecución ASP.NET para envolver HTTP y como un entorno de alojamiento CLR. Si ejecuta el modo integrado, también podrá manipular la solicitud / respuesta HTTP.
fuente