# 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
``` - Ninguna página normal `.aspx` que use `Site.master` debe declarar ``, ``, ``, `` ni ``. - No anidar formularios HTML dentro del formulario de `Site.master`. - Los formularios visuales de captura se construyen con `
`, 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 ``` - 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" %> ```