6.2 KiB
6.2 KiB
Reglas obligatorias para formularios y postbacks parciales WebForms
Estas reglas complementan AGENTS.md y AGENTS_PAGE_STRUCTURE.md.
Formulario principal
Site.masteres el único archivo autorizado para declarar el formulario principal:
<form id="form1" runat="server">
- Ninguna página normal
.aspxque useSite.masterdebe 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 placeholderC. Login.aspxes la única excepción actual porque no usaSite.mastery conserva su estructura HTML completa con su propio formulario de servidor.- No agregar una segunda excepción sin solicitud explícita.
ScriptManager
Site.masteres el único dueño delasp:ScriptManagerprincipal, actualmenteTSM.- Las páginas de contenido no deben agregar otro
ScriptManager. - Usar
asp:ScriptManagerProxysolamente cuando una página requiera registrar servicios o scripts específicos que no pertenezcan globalmente al master. - El manejo global de
AsyncPostBackErrorpermanece enSite.master.
UpdatePanel
- Usar
asp:UpdatePanelcuando una interacción deba actualizar únicamente una sección sin refrescar visualmente toda la página. - No envolver todo el placeholder
Cen un únicoUpdatePanelpor comodidad. - Crear paneles pequeños alrededor de la tabla, formulario, resumen o sección que realmente cambia.
- Preferir esta configuración:
<asp:UpdatePanel ID="UpUsuarios" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<!-- Sección que se actualiza parcialmente -->
</ContentTemplate>
</asp:UpdatePanel>
- Usar
UpdateMode="Conditional"de manera predeterminada. - Preferir
ChildrenAsTriggers="true"y aprovechar los eventos de los controles hijos; no declararAsyncPostBackTriggerpara controles que ya están dentro del mismo panel. - Llamar
Update()únicamente en paneles condicionales y sólo cuando el servidor haya modificado su contenido. - Evitar
UpdatePanelanidados. 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 colocarse dentro del panel correspondiente cuando sea apropiado; en caso contrario, registrarlos mediante
ScriptManager.RegisterAsyncPostBackControly actualizar explícitamente los paneles afectados. - Conservar
<Triggers>únicamente cuando exista una necesidad técnica. Evitar referencias declarativas a controles de otros contenedores de nombres o secciones que puedan no estar disponibles; usar la referencia del control al registrarlo medianteScriptManager. - En cada modal, colocar un solo
UpdatePanelinmediatamente dentro del segundodiv(modal-dialog), con todo elmodal-contentdentro de suContentTemplate. No dividir el contenido del mismo modal en varios paneles. - Las operaciones normales de guardar, seleccionar valores, ejecutar
RowCommandy abrir o modificar modales deben usar postbacks parciales y conservar sus eventos existentes.
Operaciones que requieren postback completo
- Conservar postbacks completos únicamente para una necesidad técnica real: cargas mediante
FileUpload, descargas que escriben directamente enResponse, exportaciones y otras respuestas incompatibles con AJAX. UsarPostBackTriggeroScriptManager.RegisterPostBackControlsegún el contenedor del control; no usarlos para botones que únicamente guardan información o actualizan la interfaz. - No intentar recibir archivos mediante
FileUploaden un postback parcial; su botón de envío debe estar registrado para postback completo. - 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:UpdateProgresscuando la operación pueda tardar lo suficiente para que el usuario necesite retroalimentación. - Asociar el indicador al
UpdatePanelcorrespondiente 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.RegisterStartupScriptcuando un script de servidor deba ejecutarse después de una actualización parcial.
Plantilla de página normal
<%@ 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="true">
<ContentTemplate>
<!-- No agregar otro form ni otro ScriptManager. -->
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
<asp:Content ID="ContentScripts" ContentPlaceHolderID="J" runat="server">
</asp:Content>