Initial commit
This commit is contained in:
102
AGENTS_WEBFORMS_PARTIAL_POSTBACKS.md
Normal file
102
AGENTS_WEBFORMS_PARTIAL_POSTBACKS.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# Reglas obligatorias para formularios y postbacks parciales WebForms
|
||||
|
||||
Estas reglas complementan `AGENTS.md` y `AGENTS_PAGE_STRUCTURE.md`.
|
||||
|
||||
## Formulario principal
|
||||
|
||||
- `Site.master` es el único archivo autorizado para declarar el formulario principal:
|
||||
|
||||
```aspx
|
||||
<form id="form1" runat="server">
|
||||
```
|
||||
|
||||
- Ninguna página normal `.aspx` que use `Site.master` debe declarar `<form>`, `<form runat="server">`, `<html>`, `<head>` ni `<body>`.
|
||||
- No anidar formularios HTML dentro del formulario de `Site.master`.
|
||||
- Los formularios visuales de captura se construyen con `<div>`, controles WebForms y validadores dentro del placeholder `C`.
|
||||
- `Login.aspx` es la única excepción actual porque no usa `Site.master` y conserva su estructura HTML completa con su propio formulario de servidor.
|
||||
- No agregar una segunda excepción sin solicitud explícita.
|
||||
|
||||
## ScriptManager
|
||||
|
||||
- `Site.master` es el único dueño del `asp:ScriptManager` principal, actualmente `TSM`.
|
||||
- Las páginas de contenido no deben agregar otro `ScriptManager`.
|
||||
- Usar `asp:ScriptManagerProxy` solamente cuando una página requiera registrar servicios o scripts específicos que no pertenezcan globalmente al master.
|
||||
- El manejo global de `AsyncPostBackError` permanece en `Site.master`.
|
||||
|
||||
## UpdatePanel
|
||||
|
||||
- Usar `asp:UpdatePanel` cuando una interacción deba actualizar únicamente una sección sin refrescar visualmente toda la página.
|
||||
- No envolver todo el placeholder `C` en un único `UpdatePanel` por comodidad.
|
||||
- Crear paneles pequeños alrededor de la tabla, formulario, resumen o sección que realmente cambia.
|
||||
- Preferir esta configuración:
|
||||
|
||||
```aspx
|
||||
<asp:UpdatePanel ID="UpUsuarios" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="false">
|
||||
<ContentTemplate>
|
||||
<!-- Sección que se actualiza parcialmente -->
|
||||
</ContentTemplate>
|
||||
<Triggers>
|
||||
<asp:AsyncPostBackTrigger ControlID="BtnBuscar" EventName="Click" />
|
||||
</Triggers>
|
||||
</asp:UpdatePanel>
|
||||
```
|
||||
|
||||
- Usar `UpdateMode="Conditional"` de manera predeterminada.
|
||||
- Preferir `ChildrenAsTriggers="false"` y declarar triggers explícitos para que el comportamiento sea fácil de revisar.
|
||||
- Llamar `Update()` únicamente en paneles condicionales y sólo cuando el servidor haya modificado su contenido.
|
||||
- Evitar `UpdatePanel` anidados. Si son necesarios, documentar qué evento actualiza cada panel.
|
||||
- No actualizar varios paneles si sólo cambió una sección.
|
||||
- Los controles externos que disparen actualización parcial deben declararse como `AsyncPostBackTrigger` o registrarse mediante `ScriptManager.RegisterAsyncPostBackControl`.
|
||||
|
||||
## Operaciones que requieren postback completo
|
||||
|
||||
- Usar `PostBackTrigger` para cargas de archivos, descargas que escriben directamente en `Response`, exportaciones y otras operaciones incompatibles con postback asíncrono.
|
||||
- No intentar procesar `FileUpload` dentro de un postback parcial sin `PostBackTrigger`.
|
||||
- No iniciar una descarga binaria desde una respuesta parcial de `UpdatePanel`.
|
||||
|
||||
## Ciclo de vida y rendimiento
|
||||
|
||||
- Un postback parcial ejecuta el ciclo de vida de servidor de la página; no significa que el servidor procese únicamente el `UpdatePanel`.
|
||||
- Proteger cargas iniciales con `if (!IsPostBack)`.
|
||||
- No repetir consultas, catálogos o construcción del menú en cada evento si no son necesarios.
|
||||
- Toda consulta continúa ejecutándose mediante contratos, servicios, repositorios y procedimientos almacenados.
|
||||
- Preferir operaciones asíncronas de extremo a extremo para consultas lentas cuando la página esté configurada correctamente para async.
|
||||
- Configurar timeouts razonables y no dejar indicadores de carga activos indefinidamente.
|
||||
|
||||
## Experiencia de usuario
|
||||
|
||||
- Usar `asp:UpdateProgress` cuando la operación pueda tardar lo suficiente para que el usuario necesite retroalimentación.
|
||||
- Asociar el indicador al `UpdatePanel` correspondiente cuando sea posible.
|
||||
- Deshabilitar temporalmente botones que puedan generar envíos duplicados.
|
||||
- Mostrar mensajes amigables dentro de la sección actualizada o mediante el sistema global de mensajes.
|
||||
- Los detalles técnicos permanecen exclusivamente en el log.
|
||||
|
||||
## JavaScript después de un postback parcial
|
||||
|
||||
- Los scripts registrados globalmente no deben duplicarse dentro de un `UpdatePanel`.
|
||||
- Los componentes JavaScript que pierdan inicialización después de reemplazar HTML deben reinicializarse mediante `Sys.WebForms.PageRequestManager.endRequest`.
|
||||
- Evitar registrar múltiples veces el mismo handler en cada postback parcial.
|
||||
- Usar `ScriptManager.RegisterStartupScript` cuando un script de servidor deba ejecutarse después de una actualización parcial.
|
||||
|
||||
## Plantilla de página normal
|
||||
|
||||
```aspx
|
||||
<%@ Page Title="Página" Language="C#" MasterPageFile="~/Site.master"
|
||||
AutoEventWireup="true" CodeBehind="Pagina.aspx.cs"
|
||||
Inherits="SIG.Web.Pages.Modulo.Pagina" %>
|
||||
|
||||
<asp:Content ID="ContentHead" ContentPlaceHolderID="H" runat="server">
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="ContentMain" ContentPlaceHolderID="C" runat="server">
|
||||
<asp:UpdatePanel ID="UpContenido" runat="server"
|
||||
UpdateMode="Conditional" ChildrenAsTriggers="false">
|
||||
<ContentTemplate>
|
||||
<!-- No agregar otro form ni otro ScriptManager. -->
|
||||
</ContentTemplate>
|
||||
</asp:UpdatePanel>
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="ContentScripts" ContentPlaceHolderID="J" runat="server">
|
||||
</asp:Content>
|
||||
```
|
||||
Reference in New Issue
Block a user