GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Sé diferente, intégrate… Mm081 Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Autor: Orlando Gutiérrez Fecha: 01/01/2011 1 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 INDICE 1 CONFIGURAR PROVEEDORES DE DATOS: PERSONALIZACIÓN, MIEMBROS, FUENTES DE DATOS, MAPA DEL SITIO, RECURSOS, SEGURIDAD .......................................................................................................................... 5 CONTROLES DE ORIGEN DE DATOS ........................................................................................................ 5 MAPA DEL SITIO .................................................................................................................................. 6 CONTROLES DE EXPLORACIÓN DEL SITIO ............................................................................................... 7 PROTEGER EL ACCESO DE DATOS .......................................................................................................... 8 2 CONFIGURAR LA AUTENTICACIÓN, AUTORIZACIÓN Y LA REPRESENTACIÓN: AUTENTICACIÓN DE FORMULARIOS, AUTENTICACIÓN DE WINDOWS ............................................................................................................... 9 ARQUITECTURA DE SEGURIDAD DE ASP.NET ........................................................................................... 9 AUTENTICACIÓN DE ASP.NET ............................................................................................................... 12 PROVEEDOR DE AUTENTICACIÓN DE WINDOWS...................................................................................... 13 PROVEEDOR DE AUTENTICACIÓN MEDIANTE FORMULARIOS ..................................................................... 14 3 CONFIGURAR PROYECTOS, SOLUCIONES Y CONJUNTOS DE REFERENCIAS: CONJUNTOS LOCALES, CONJUNTOS COMPARTIDOS (GAC), PROYECTOS DE APLICACIONES WEB, SOLUCIONES ............................................. 19 COLOCACIÓN DE ENSAMBLADOS .......................................................................................................... 20 CACHÉ DE ENSAMBLADOS GLOBAL........................................................................................................ 20 4 CONFIGURAR EL ESTADO DE LA SESIÓN UTILIZANDO MICROSOFT SQL SERVER, STATE SERVER O INPROC: CONFIGURACIÓN DEL TIEMPO DE ESPERA; SESIONES SIN COOKIES ...................................................... 21 ESTADO DE SESIÓN DE ASP.NET .......................................................................................................... 21 MODOS DE ESTADO DE SESIÓN ............................................................................................................ 21 MODO EN PROCESO “IN PROC” ............................................................................................................. 22 MODO SERVIDOR DE ESTADO “STATE SERVER” ...................................................................................... 22 MODO SQL SERVER............................................................................................................................. 22 MODO PERSONALIZADO ...................................................................................................................... 24 5 PUBLICAR APLICACIONES WEB: SISTEMA DE ARCHIVOS O HTTP DE VISUAL STUDIO .......................... 25 6 CONFIGURAR CONJUNTOS DE APLICACIONES ..................................................................................... 28 7 COMPILAR UNA APLICACIÓN UTILIZANDO VISUAL STUDIO O HERRAMIENTAS DE LÍNEA DE COMANDO: ASPNET_COMPILER.EXE, COMPILACIÓN JUST-IN-TIME (JIT), ASPNET_MERGE.EXE ................................ 29 HERRAMIENTA DE COMPILACIÓN DE ASP.NET (Aspnet_compiler.exe) ......................................................... 29 HERRAMIENTA DE COMBINACIÓN DE ASP.NET (Aspnet_merge.exe) ........................................................... 33 ARGUMENTOS .................................................................................................................................... 34 OPCIONES ......................................................................................................................................... 34 REALIZAR LA COMPILACIÓN CON EL COMPILADOR Just-In-Time (JIT) ......................................................... 40 8 IMPLEMENTAR CONTROLES ASOCIADOS CON DATOS: DATAGRID, DATALIST, REPEATER, LISTVIEW, GRIDVIEW, FORMVIEW, DETAILSVIEW, TREEVIEW, DATAPAGER.............................................................................. 40 9 CARGAR LOS CONTROLES DEL USUARIO DINÁMICAMENTE.................................................................. 42 10 CREAR Y UTILIZAR CONTROLES PERSONALIZADOS: REGISTRO DE CONTROLES EN UNA PÁGINA, CREACIÓN DE CONTROLES EN PLANTILLA.................................................................................................................... 44 2 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 CONTROL DE SERVIDOR CON PLANTILLA ............................................................................................... 52 11 IMPLEMENTAR LA VALIDACIÓN EN EL CLIENTE Y EN EL SERVIDOR: REQUIREDFIELDVALIDATOR, COMPAREVALIDATOR, REGULAREXPRESSIONVALIDATOR, CUSTOMVALIDATOR, RANGEVALIDATOR ....... 63 VALIDAR LA INFORMACIÓN ESPECIFICADA POR EL USUARIO EN PÁGINAS WEB ASP.NET .............................. 63 TIPOS DE VALIDACIÓN Y CONTROLES.................................................................................................... 65 12 UTILIZAR CONTROLES ESTÁNDAR: BUTTON, TEXTBOX, DROPDOWNLIST, RADIOBUTTON, CHECKBOX, HYPERLINK, WIZARD, MULTIVIEW ........................................................................................................ 66 BUTTON ............................................................................................................................................ 66 13 LEER Y ESCRIBIR DATOS XML: XMLDOCUMENT, XPATHNAVIGATOR, XPATHNODEITERATOR, XPATHDOCUMENT, XMLREADER, XMLWRITER, XMLDATADOCUMENT, XMLNAMESPACEMANAGER ............ 68 14 MANIPULAR LOS DATOS UTILIZANDO LOS OBJETOS DATASET Y DATAREADER .................................. 70 ARQUITECTURA DE ADO.NET ................................................................................................................ 70 15 LLAMAR A UN SERVICIO WINDOWS COMMUNICATION FOUNDATION (WCF) O A UN SERVICIO WEB DESDE UNA PÁGINA WEB ASP.NET: APP_WEBREFERENCES; <SYSTEM.SERVICEMODEL> CONFIGURATION .................................................................................................................................. 71 CONSUMO DE SERVICIOS WCF ............................................................................................................. 71 SERVICIOS WEB ................................................................................................................................. 74 16 IMPLEMENTAR UN CONTROL DATASOURCE: LINQDATASOURCE, OBJECTDATASOURCE, XMLDATASOURCE, SQLDATASOURCE ..................................................................................................... 75 17 VINCULAR LOS CONTROLES A LOS DATOS UTILIZANDO LA SINTAXIS DE UNIÓN DE DATOS (DATA BINDING) ............................................................................................................................................. 77 EL MECANISMO DEL ENLACE A DATOS ................................................................................................... 77 18 CONFIGURAR LA DEPURACIÓN Y LOS ERRORES PERSONALIZADOS. PUEDE INCLUIR, PERO SIN LIMITARSE A ELLO: <CUSTOMERRORS MODE="OFF|ON|REMOTEONLY" />, <COMPILATION DEBUG="TRUE"/> ................................................................................................................................ 80 HABILITAR LA DEPURACIÓN EN ASP.NET ................................................................................................ 80 19 CONFIGURAR UN ENTORNO PARA REALIZAR LA DEPURACIÓN REMOTA ............................................. 82 20 DEPURAR LAS EXCEPCIONES SIN TRAZAR AL UTILIZAR ASP.NET AJAX: MÉTODOS SYS.DEBUG EN EL CLIENTE; CONEXIÓN DE UN PROGRAMA DE DEPURACIÓN A WINDOWS INTERNET EXPLORER ................ 83 21 IMPLEMENTAR EL SEGUIMIENTO DE UNA APLICACIÓN WEB: TRACE.AXD, TRACE=TRUE ON @PAGE DIRECTIVE,<TRACE ENABLED="TRUE"/> .............................................................................................. 89 22 DEPURAR LOS PROBLEMAS DE IMPLEMENTACIÓN: ASPNET_REGIIS.EXE; CREACIÓN DE UNA APLICACIÓN WEB IIS; CONFIGURACIÓN DE LA VERSIÓN DE .NET FRAMEWORK ..................................... 96 aspnet_regiis [opciones] ...................................................................................................................... 96 OPCIONES DE CONFIGURACIÓN............................................................................................................ 97 23 SUPERVISAR APLICACIONES WEB: SUPERVISIÓN DE LA SALUD UTILIZANDO WEBEVENT, CONTADORES DE RENDIMIENTO............................................................................................................ 98 USAR LOS EVENTOS DE SUPERVISIÓN DE ESTADO DE ASP.NET .............................................................. 100 3 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 UTILIZAR EVENTOS WEB Y PROVEEDORES INTEGRADOS ........................................................................ 100 24 IMPLEMENTAR FORMULARIOS WEB UTILIZANDO ASP.NET AJAX: ENABLEPARTIALRENDERING, TRIGGERS, CHILDRENASTRIGGERS, SCRIPTS, SERVICES, UPDATEPROGRESS, TIMER, SCRIPTMANAGERPROXY ...................................................................................................................... 101 CONTROL TIMER ............................................................................................................................... 102 CONTROL UPDATE PANEL ................................................................................................................... 103 ESPECIFICAR LOS DESENCADENADORES (TRIGGERS) DE UPDATEPANEL .................................................. 104 25 INTERACTUAR CON LA BIBLIOTECA EN EL CLIENTE ASP.NET AJAX: OBJETOS JAVASCRIPT OBJECT NOTATION (JSON); TRATAMIENTO DE EVENTOS ASP.NET AJAX ........................................................... 105 INTRODUCCIÓN ............................................................................................................................... 105 UTILIZANDO SINTAXIS JSON CON AJAX ............................................................................................... 106 DEVOLVIENDO DATOS EN UN FORMATO JSON DESDE UN SERVICIO WEB ASP.NET SOBRE HTTP .................. 106 ENTENDIENDO EL PARÁMETRO ‘D’ EN LOS DATOS ASP.NET AJAX JSON .................................................... 107 AJAX DE ASP.NET: INTERIOR DE LA CADENA DE FECHA Y HORA DE JSON ................................................. 107 26 USAR SERVICIOS DE SCRIPTS DE CLIENTE...................................................................................... 108 CONSUMO DE SERVICIOS DE DATOS MEDIANTE LA BIBLIOTECA AJAX DE ASP.NET .................................... 108 USO DE LA CLASE OPENDATACONTEXT ................................................................................................ 108 27 CREAR Y REGISTRAR UN SCRIPT DE CLIENTE: INLINE, ARCHIVO .JS INCLUIDO, RECURSO JAVASCRIPT INCRUSTADO, CREADO DESDE EL CÓDIGO DE SERVIDOR ................................................. 111 28 PROGRAMAR DISPOSITIVOS MÓVILES ............................................................................................ 113 ASP.NET MOBILE WEB FORMS Y COMPATIBILIDAD CON ASP.NET ............................................................. 115 29 ACCESO A LAS CAPACIDADES DEL DISPOSITIVO: TRABAJO CON EMULADORES ............................... 117 30 CONTROLAR EL PROCESAMIENTO ESPECÍFICO DEL DISPOSITIVO: CONTROL DEVICESPECIFIC; FILTROS DE DISPOSITIVO; PLANTILLAS DE CONTROL ......................................................................... 118 31 AGREGAR CONTROLES WEB MÓVILES A UNA PÁGINA WEB: CONTROLES STYLESHEET; CONTROLES LIST; CONTROLES CONTAINER ............................................................................................................ 120 32 IMPLEMENTAR ADAPTADORES DE CONTROL: APP_BROWSERS; PROCESAMIENTO UTILIZANDO CHTMLTEXTWRITER O XHTMLTEXTWRITER .......................................................................................... 121 33 PERSONALIZAR EL DISEÑO Y APARIENCIA DE UNA PÁGINA WEB: CSS, TEMAS Y FUNCIONES, PÁGINAS PRINCIPALES Y ELEMENTOS WEB, APP_THEMES, STYLESHEETTHEME ................................... 129 TEMAS Y MÁSCARAS DE ASP.NET ........................................................................................................ 129 CONTROLES DE SERVIDOR WEB ASP.NET Y ESTILOS DE CSS .................................................................. 132 34 TRABAJAR CON OBJETOS INTRÍNSECOS DE ASP.NET: REQUEST, SERVER, APPLICATION, SESSION, RESPONSE, HTTPCONTEXT................................................................................................................... 135 35 IMPLEMENTAR LA GLOBALIZACIÓN Y ACCESIBILIDAD: ARCHIVOS DE RECURSOS, CONFIGURACIÓN DE CULTURA, REGIONINFO, APP_GLOBALRESOURCES, APP_LOCALRESOURCES, TABINDEX, ALTERNATETEXT , GENERATEEMPTYALTERNATETEXT, ACCESSKEY, LABEL.ASSOCIATEDCONTROLID ..... 137 INFORMACIÓN GENERAL SOBRE LA GLOBALIZACIÓN Y LA LOCALIZACIÓN ................................................ 137 CONCEPTOS COMUNES DE RECURSOS ................................................................................................. 138 4 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 CÓMO: CREAR ARCHIVOS DE RECURSOS PARA SITIOS WEB ASP.NET ...................................................... 140 CREAR UNA APLICACIÓN WEB ACCESIBLE ............................................................................................ 142 CÓMO: CREAR ARCHIVOS DE RECURSOS PARA SITIOS WEB ASP.NET ...................................................... 140 36 IMPLEMENTAR OBJETOS EMPRESARIALES Y CLASES DE UTILIDAD: APP_CODE , CONJUNTOS EXTERNOS........................................................................................................................................... 143 INFORMACIÓN GENERAL SOBRE LA GLOBALIZACIÓN Y LA LOCALIZACIÓN ................................................ 137 37 IMPLEMENTAR EL ESTADO DE SESIÓN, VER EL ESTADO, CONTROLAR EL ESTADO, COOKIES, CACHÉ O ESTADO DE LA APLICACIÓN ............................................................................................................. 145 38 TRATAR EVENTOS Y CONTROLAR EL FLUJO DE PÁGINAS: EVENTOS DE PÁGINA, EVENTOS DE CONTROL, EVENTOS DE APLICACIÓN Y EVENTOS DE SESIÓN, PUBLICACIONES EN VARIAS PÁGINAS; RESPONSE.REDIRECT, SERVER.TRANSFER, ISPOSTBACK, CONFIGURACIÓN DE AUTOEVENTWIREUP IMPLEMENTAR EL CONTROLADOR GENERIC ......................................................................................... 148 MODELO DE EVENTOS DE CONTROL DE SERVIDOR WEB ASP.NET ............................................................ 148 5 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 1 CONFIGURAR PROVEEDORES DE DATOS: PERSONALIZACIÓN, MIEMBROS, FUENTES DE DATOS, MAPA DEL SITIO, RECURSOS, SEGURIDAD Las aplicaciones Web obtienen acceso normalmente a los orígenes de datos para el almacenamiento y la recuperación de datos dinámicos. Se puede escribir código para el acceso a los datos utilizando clases del espacio de nombres System.Data (normalmente denominado ADO.NET) y del espacio de nombres System.Xml. Este enfoque era normal en versiones anteriores de ASP.NET. Sin embargo, ASP.NET también permite realizar el enlace de datos mediante declaración. Este proceso no requiere la existencia de código para los escenarios de datos más comunes, entre los que se incluyen: Seleccionar y mostrar datos. Ordenar, paginar y almacenar datos en memoria caché. Actualizar, insertar y eliminar datos. Filtrar datos utilizando parámetros en tiempo de ejecución. Crear escenarios de detalles maestros utilizando parámetros. ASP.NET incluye dos tipos de controles de servidor que participan en el modelo de enlace de datos declarativo: controles de origen de datos y controles enlazados a datos. Estos controles administran las tareas subyacentes requeridas por el modelo Web sin estado para mostrar y actualizar datos en páginas Web ASP.NET. Por tanto, no es estrictamente necesario conocer los detalles del ciclo de vida de la solicitud de página si sólo se va a realizar el enlace de datos. CONTROLES DE ORIGEN DE DATOS Los controles de origen de datos son controles ASP.NET que administran las tareas de conexión a un origen de datos y de lectura y escritura de datos. Los controles de origen de datos no representan ninguna interfaz de usuario, sino que actúan como intermediarios entre un almacén de datos en particular (como una base de datos, un objeto comercial o un archivo XML) y los demás controles de la página Web ASP.NET. Los controles de origen de datos habilitan un amplio conjunto de funciones para recuperar y modificar datos, entre las que se incluyen la consulta, la ordenación, la paginación, el filtrado, la actualización, la eliminación y la inserción. ASP.NET incluye los controles de origen de datos siguientes: AccessDataSource Permite trabajar con una base de datos de Microsoft Access. LinqDataSource Permite usar Language-Integrated Query (LINQ) en una página web ASP.NET a través de marcado declarativo para recuperar y modificar datos de un objeto de datos. Admite la generación automática de comandos de selección, actualización, inserción y eliminación. El control también admite ordenación, filtrado y paginación. ObjectDataSource Permite trabajar con un objeto comercial u otra clase y crear aplicaciones Web basadas en objetos de nivel medio para administrar los datos. SiteMapDataSource Se utiliza con la navegación en el sitio ASP.NET. SqlDataSource Permite trabajar con proveedores de datos administrados de ADO.NET, que proporcionan acceso a bases de datos de Microsoft SQL Server, OLE DB, ODBC u Oracle. XmlDataSource Permite trabajar con un archivo XML, que es especialmente útil para controles de servidor ASP.NET jerárquicos tales como el control TreeView o Menu. 6 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Los controles de origen de datos también se pueden ampliar para admitir proveedores de almacenamiento y acceso a datos adicionales. MAPA DEL SITIO Puede utilizar las características de exploración del sitio de ASP.NET con el fin de proporcionar una manera coherente a los usuarios para explorar el sitio. Cuando un sitio crece y cuando se mueven sus páginas, puede resultar complicado administrar todos los vínculos. La exploración del sitio de ASP.NET permite almacenar los vínculos de todas las páginas en una ubicación central y representar estos vínculos en listas o menús de desplazamiento en cada página incluyendo un control de servidor Web específico. Con la exploración del sitio de ASP.NET, puede crear una solución de exploración consistente y fácil de administrar para el sitio. La exploración del sitio de ASP.NET cuenta con las características siguientes: Mapas del sitio Se puede utilizar un mapa del sitio para describir la estructura lógica de su sitio. Se puede administrar la exploración de la página modificando el mapa del sitio cuando se agregan o se eliminan páginas en lugar de modificar los hipervínculos en todas las páginas Web. Controles ASP.NET Se puede utilizar estos controles para mostrar los menús de exploración en las páginas Web. Los menús de exploración se basan en el mapa del sitio. Control de programación Se puede utilizar la exploración del sitio de ASP.NET en el código para crear controles de exploración personalizados o modificar la ubicación de la información que se muestra en un menú de desplazamiento. Reglas de acceso Se puede configurar reglas de acceso para mostrar u ocultar un vínculo en el menú de desplazamiento. Proveedores de mapas de sitio personalizados Se puede crear proveedores de mapas de sitio personalizados permitiendo trabajar con el propio servidor del mapa del sitio (por ejemplo, una base de datos donde almacene la información de los vínculos) y conectar el proveedor al sistema de exploración del sitio de ASP.NET. En la ilustración siguiente se muestran las relaciones existentes entre los componentes de exploración del sitio de ASP.NET. 7 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 CONTROLES DE EXPLORACIÓN DEL SITIO Crear un mapa del sitio reflejando la estructura del sitio es una parte del sistema de exploración del sitio de ASP.NET. La otra parte es mostrar la estructura de exploración en las páginas Web ASP.NET para que los usuarios puedan desplazarse por el sitio con facilidad. Se puede establecer la exploración en las páginas de forma sencilla utilizando los siguientes controles de desplazamiento del sitio de ASP.NET: SiteMapPath Este control muestra una ruta de desplazamiento indicando al usuario la ubicación de la página actual y mostrando los vínculos como una ruta de retorno a la página principal. El control proporciona muchas opciones para personalizar el aspecto de los vínculos. TreeView Este control muestra una estructura de árbol, o de menú, que los usuarios pueden recorrer para llegar a diferentes páginas del sitio. Se puede expandir o contraer un nodo conteniendo nodos secundarios haciendo clic en él. Menu Este control muestra un menú expansible a los usuarios para recorrer llegando a diferentes páginas del sitio. Un nodo conteniendo nodos secundarios se expandirá cuando el cursor se sitúe sobre el menú. 8 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Puede utilizar el control SiteMapPath para crear la exploración del sitio sin código y sin enlaces de datos explícitos. El control puede leer y representar la información del mapa del sitio automáticamente. Sin embargo, si es necesario, también se puede personalizar el control SiteMapPath mediante código. El control SiteMapPath permite a los usuarios desplazarse hacia atrás desde la página actual a las páginas superiores en la jerarquía del sitio. Sin embargo, el control SiteMapPath no le permite desplazarse hacia delante desde la página actual a otra página más profunda en la jerarquía. El control SiteMapPath es útil para las aplicaciones de grupos de noticias o mensajería cuando los usuarios desean ver la ruta de acceso al artículo que están explorando. Con los controles TreeView o Menu, los usuarios pueden abrir los nodos y desplazarse directamente a una página determinada. Estos controles no leen el mapa del sitio directamente, puesto que ya lo hace el control SiteMapPath. En su lugar, se puede agregar un control SiteMapDataSource a una página que pueda leer el mapa del sitio. A continuación, se puede enlazar el control TreeView o Menu al control SiteMapDataSource, lo que hace que el mapa del sitio se represente en la página. PROTEGER EL ACCESO A DATOS La mayoría de las aplicaciones Web ASP.NET implican el acceso a datos. Muchas aplicaciones recogen datos para almacenarlos en una base de datos o en un archivo y, a menudo, se basan en información procedente de los usuarios. Puesto que los datos originales pueden proceder de orígenes no de confianza (y la información se almacena en un formato permanente) y se debe asegurar que los usuarios no autorizados no puedan obtener acceso al origen de datos directamente, es necesario prestar especial atención a los problemas de seguridad relacionados con el acceso a datos. Aunque se puede mejorar la seguridad de la aplicación siguiendo las buenas prácticas en materia de codificación y configuración, también es importante mantener actualizado el servidor Web con las últimas actualizaciones de seguridad de Microsoft Windows e Internet Information Services (IIS), así como las actualizaciones de seguridad de Microsoft SQL Server o cualquier otro software de base de datos. Proteger el acceso a un origen de datos Cadenas de conexión: Para conectar con una base de datos, se necesita una cadena de conexión. Puesto que las cadenas de conexión pueden contener datos confidenciales, se deben seguir estas instrucciones: a) No almacenar cadenas de conexión en ninguna página. Por ejemplo, evite la configuración de las cadenas de conexión como propiedades declarativas del control SqlDataSource o de otros controles de origen de datos. En su lugar, almacénelas en el archivo Web.config del sitio. b) No almacenar cadenas de conexión como texto sin formato. Para proteger la conexión al servidor de base de datos, se recomienda cifrar la información de la cadena de conexión del archivo de configuración mediante la configuración protegida. Conectar con SQL Server mediante seguridad integrada: En lo posible conectarse a una instancia de SQL Server utilizando la seguridad integrada en lugar de un nombre de usuario explícito y una contraseña. De esta forma, se evita la posibilidad de comprometer la integridad de la cadena de conexión y de exponer el identificador de usuario y la contraseña. Se recomienda asegurarse de la identidad del proceso (por ejemplo, la agrupación de aplicaciones) ejecutando ASP.NET sea la cuenta de proceso predeterminada o una cuenta de usuario restringida. En los casos donde distintos sitios Web conectan con diversas bases de datos de SQL Server, puede no resultar práctico utilizar la seguridad integrada. Por ejemplo, en los sitios de alojamiento Web, se suele asignar a cada cliente una base de datos de SQL Server diferente, pero todos utilizan el servidor Web como usuarios anónimos. En estos casos, debe utilizar credenciales explícitas para conectarse a una instancia de SQL Server. Asegúrese de almacenar las credenciales de forma segura. Permisos de base de datos de SQL Server Se recomienda asignar los privilegios mínimos al identificador de usuario utilizado para la conexión a las bases de datos de SQL Server usadas en la aplicación. Restringir las operaciones de SQL Los controles enlazados a datos pueden admitir una gran variedad de operaciones con datos como selección, inserción, eliminación y actualización de registros en las tablas de datos. Se recomienda configurar los controles de datos para realizar la funcionalidad 9 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 mínima necesaria de la página o aplicación. Por ejemplo, si un control no debe permitir a los usuarios que eliminar datos, no se debe incluir una consulta Delete con un control de origen de datos y no permitir eliminación en el control. Protegerse de los datos de entrada malintencionados Si la aplicación acepta la entrada de datos de los usuarios, debe asegurar su contenido no es malintencionado y no compromete la integridad de la aplicación. Los usuarios malintencionados pueden introducir datos para iniciar los siguientes ataques: a) Inyección de secuencia de comandos Un ataque de inyección consiste en enviar una secuencia de comandos a la aplicación para que otros usuarios la ejecuten. En los ataques de inyección típicos, las secuencias de comandos se envían a una página almacenándolas en una base de datos, de modo que otro usuario que vea los datos ejecute el código sin darse cuenta. b) Inyección SQL Los ataques de inyección SQL intentan comprometer la seguridad de la base de datos, y posiblemente la del equipo en el que se está ejecutando, creando comandos de SQL que se ejecutan sustituyendo o sumándose a los integrados en la aplicación. 2 CONFIGURAR LA AUTENTICACIÓN, AUTORIZACIÓN Y LA REPRESENTACIÓN: AUTENTICACIÓN DE FORMULARIOS, AUTENTICACIÓN DE WINDOWS ASP.NET, conjuntamente con Microsoft Internet Information Services (IIS), puede autenticar las credenciales del usuario como nombres y contraseñas mediante los métodos de autenticación siguientes: Windows: básica, implícita, y Autenticación de Windows integrada (NTLM o Kerberos). Autenticación mediante formularios, con la que crea una página de inicio de sesión y se administra la autenticación en la aplicación. Autenticación mediante certificados de cliente ASP.NET controla el acceso a la información de los sitios comparando las credenciales autenticadas, o representaciones de las mismas, con los permisos del sistema de archivos de Microsoft Windows NT o con un archivo XML conteniendo la lista de usuarios autorizados, funciones autorizadas (grupos) o verbos HTTP autorizados. Para ayudar a proteger la seguridad de una aplicación ASP.NET, se deben llevar a cabo las dos funciones principales descritas en la siguiente tabla. Función de seguridad Descripción Autenticación Ayuda a comprobar que el usuario es precisamente quien dice ser. La aplicación obtiene las credenciales (diversas formas de identificación, como nombre y contraseña) de un usuario, y las valida consultando a una autoridad determinada. Si las credenciales son válidas, se considera a la entidad enviando las credenciales como una entidad autenticada. Autorización Limita los derechos de acceso mediante la concesión o negación de permisos específicos a una identidad autenticada. Además, Internet Information Services (IIS) puede conceder o negar el acceso en función de la dirección IP o del nombre de host del usuario. Cualquier autorización de acceso posterior se realiza mediante la autorización de la dirección URL del permiso de acceso al sistema de archivos NTFS. Es importante entender cómo interactúan todos los diversos subsistemas de seguridad. Puesto que ASP.NET se basa en Microsoft .NET Framework, el desarrollador de aplicaciones ASP.NET también tiene acceso a todas las características de seguridad integradas de .NET Framework, como la seguridad de acceso a código y la seguridad de acceso basada en funciones ARQUITECTURA DE SEGURIDAD DE ASP.NET En esta sección se proporciona información general sobre la infraestructura de seguridad de ASP.NET. En la siguiente ilustración se muestran las relaciones entre los sistemas de seguridad de ASP.NET. 10 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Como se muestra en la ilustración, todos los clientes Web se comunican con las aplicaciones ASP.NET a través de Microsoft Internet Information Services (IIS). IIS autentica la solicitud si fuera necesario y, a continuación, busca el recurso solicitado (como una aplicación ASP.NET). Si el cliente está autorizado, el recurso estará disponible. Cuando se está ejecutando una aplicación ASP.NET, puede utilizar las características de seguridad de ASP.NET integradas. Además, una aplicación ASP.NET puede utilizar las características de seguridad de .NET Framework 11 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Flujo de datos en Seguridad .Net Por Windows 12 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Por formularios AUTENTICACIÓN DE ASP.NET La autenticación es un proceso que consiste en obtener las credenciales de identificación, como nombre y contraseña, de un usuario y validarlas consultando a una autoridad determinada. Si las credenciales son válidas, se considera a la entidad que ha enviado las credenciales como una entidad autenticada. Una vez autenticada la identidad, el proceso de autorización determina si esa identidad tiene acceso a un recurso específico. ASP.NET implementa este proceso a través de proveedores de autenticación, módulos conteniendo el código necesario para autenticar las credenciales del solicitante. Proveedor de autenticación de Windows Proporciona información sobre cómo utilizar la autenticación de Windows junto con la autenticación de Microsoft Internet Information Services (IIS) para proteger las aplicaciones ASP.NET. Proveedor de autenticación mediante formularios Proporciona información sobre cómo crear un formulario de inicio de sesión específico de la aplicación y realizar la autenticación mediante código propio. Una manera sencilla de trabajar con la autenticación de formularios consiste en utilizar la suscripción de 13 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 ASP.NET y los controles de inicio de sesión de ASP.NET, que conjuntamente proporcionan un método para recopilar las credenciales de usuario, autenticarlas y administrarlas, con muy poco código o nada en absoluto. PROVEEDOR DE AUTENTICACIÓN DE WINDOWS La Autenticación de Windows trata la identidad de usuario proporcionada por Servicios de Microsoft Internet Information Server (IIS) como el usuario autenticado en una aplicación ASP.NET. IIS ofrece diversos mecanismos de autenticación para comprobar la identidad del usuario, incluyendo autenticación anónima, autenticación de Windows integrada (NTLM), autenticación de Windows integrada (Kerberos), autenticación básica (codificada en base64), autenticación de texto implícita y autenticación basada en certificados de cliente. La autenticación de Windows se implementa en ASP.NET utilizando el módulo WindowsAuthenticationModule. El módulo construye una identidad WindowsIdentity basándose en las credenciales proporcionadas por IIS y establece la identidad como el valor actual de la propiedad User para la aplicación. La autenticación de Windows es el mecanismo de autenticación predeterminado para las aplicaciones ASP.NET y se identifica como el modo de autenticación para una aplicación mediante el elemento de configuración authentication, tal como se muestra en el ejemplo de código siguiente. <system.web> <authentication mode="Windows"/> </system.web> Suplantar la identidad de Windows El modo de autenticación de Windows establece el valor de la propiedad User actual en una identidad WindowsIdentity basándose en las credenciales proporcionadas por IIS, no modifica la identidad de Windows proporcionada al sistema de operación. La identidad de Windows proporcionada al sistema operativo se utiliza para comprobar los permisos, como los permisos de archivos NTFS, o para conectarse a una base de datos mediante la seguridad integrada. De forma predeterminada, esta identidad de Windows es la identidad del proceso de ASP.NET. En Microsoft Windows 2000 y Windows XP Professional, ésta es la identidad del proceso de trabajo de ASP.NET, la cuenta local de ASPNET. En Windows Server 2003, ésta es la identidad del Grupo de aplicaciones IIS de la aplicación ASP.NET. De forma predeterminada, ésta es la cuenta NETWORK SERVICE. Para configurar la identidad de Windows de la aplicación ASP.NET como la identidad de Windows proporcionada por IIS se debe habilitar la suplantación. Es decir, indicar a la aplicación ASP.NET suplantar la identidad suministrada por IIS para todas las tareas autenticadas por el sistema de operación Windows, incluyendo el acceso a archivos y a la red. Para habilitar la suplantación para la aplicación Web, en el archivo Web.config de la aplicación se establece el atributo impersonate del elemento identity en true, como se muestra en el ejemplo de código siguiente. <system.web> <authentication mode="Windows"/> <identity impersonate="true"/> </system.web> Habilitar la autorización utilizando ACL de NTFS Se puede mejorar la seguridad de una aplicación ASP.NET protegiendo los archivos de la aplicación mediante el sistema de archivos NTFS y Listas de control de acceso (ACL). Las ACL permiten especificar cuáles usuarios y grupos de usuarios tienen acceso a los archivos de la aplicación. 14 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 PROVEEDOR DE AUTENTICACIÓN MEDIANTE FORMULARIOS Se presenta una implementación simple de la autenticación mediante formularios de ASP.NET. Está diseñada para mostrar los principios de cómo utilizar la autenticación mediante formularios para registrar a los usuarios en una aplicación ASP.NET. La forma útil de trabajar con la autenticación mediante formularios es utilizar la suscripción y los controles de inicio de sesión de ASP.NET. La suscripción de ASP.NET proporciona un medio para almacenar y administrar la información de los usuarios e incluye métodos para su autenticación. Los controles de inicio de sesión de ASP.NET funcionan con la suscripción de ASP.NET y encapsulan la lógica requerida para solicitar credenciales a los usuarios, validarlos, recuperar o reemplazar contraseñas, etc. Efectivamente, la suscripción y los controles de inicio de sesión de ASP.NET proporcionan una capa de abstracción en la autenticación mediante formularios y reemplazan la mayor parte del trabajo que tendría que llevarse a cabo normalmente para utilizar dicha autenticación. En el escenario del ejemplo los usuarios solicitan un recurso protegido, concretamente una página denominada Default.aspx. Solamente un usuario tiene acceso al recurso protegido: alumno@institutogala.com, con la contraseña "WakaMaY@". El nombre de usuario y la contraseña están incluidos en el código del archivo Logon.aspx. El ejemplo requiere tres archivos: el archivo Web.config, una página denominada Logon.aspx, y una página denominada Default.aspx. Los archivos residen en el directorio raíz de la aplicación. Para configurar la aplicación para la autenticación mediante formularios 1. Colocar en el archivo Web.config de la carpeta raíz de la aplicación los siguientes elementos: <?xml version="1.0"?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <system.web> </system.web> </configuration> 2. Dentro del elemento system.web, crear un elemento authentication y establecer el atributo mode en Forms, como se muestra en el ejemplo siguiente: <system.web> <authentication mode="Forms"> </authentication> </system.web> 3. Dentro del elemento authentication, crear un elemento forms y establecer los atributos siguientes: loginUrl Establecer este atributo en "Logon.aspx". Logon.aspx es la dirección URL a utilizar para el redireccionamiento si ASP.NET no encuentra una cookie de autenticación con la solicitud. name Establezca este atributo en ".ASPXFORMSAUTH". De este modo se establece el sufijo del nombre de la cookie conteniendo el “token” de autenticación. <system.web> <authentication mode="Forms"> <forms loginUrl="Logon.aspx" name=".ASPXFORMSAUTH"> </forms> </authentication> </system.web> 4. Dentro del elemento system.web, crear un elemento authorization. <system.web> 15 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 <authentication mode="Forms"> <forms loginUrl="Logon.aspx" name=".ASPXFORMSAUTH"> </forms> </authentication> <authorization> </authorization> </system.web> 5. Dentro del elemento authorization, crear un elemento deny y establezca su atributo users en "?". Esto especifica que los usuarios no autenticados (representados por "?") no tienen acceso a los recursos de esta aplicación. <authentication mode="Forms"> <forms loginUrl="logon.aspx" name=".ASPXFORMSAUTH"></forms> </authentication> <authorization> <deny users="?" /> </authorization> </system.web> Crear la página de inicio de sesión Cuando los usuarios solicitan cualquier página del sitio Web y no se han autenticado previamente, son redirigidos a una página denominada Logon.aspx. Este nombre de archivo ya se ha especificado anteriormente en el archivo Web.config. La página Logon.aspx recoge las credenciales del usuario (dirección de correo electrónico y contraseña) y las autentica. Si el usuario es autenticado correctamente, la página de inicio de sesión le redirige a la página solicitada originalmente. En el ejemplo, las credenciales válidas están incluidas en el código de la página. 1. Crear una página ASP.NET denominada Logon.aspx en la carpeta raíz de la aplicación. 2. Copiar el marcado siguiente y codifique en él: <%@ Page Language="C#" %> <%@ Import Namespace="System.Web.Security" %> <script runat="server"> void Logon_Click(object sender, EventArgs e) { if ((UserEmail.Text == " alumno@institutogala.com") && (UserPass.Text == " WakaMaY@")) { 16 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 FormsAuthentication.RedirectFromLoginPage (UserEmail.Text, Persist.Checked); } else { Msg.Text = "Invalid credentials. Please try again."; } } </script> <html> <head id="Head1" runat="server"> <title>Forms Authentication - Login</title> </head> <body> <form id="form1" runat="server"> <h3> Logon Page</h3> <table> <tr> <td> E-mail address:</td> <td> <asp:TextBox ID="UserEmail" runat="server" /></td> <td> <asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="UserEmail" Display="Dynamic" ErrorMessage="Cannot be empty." runat="server" /> </td> </tr> 17 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 <tr> <td> Password:</td> <td> <asp:TextBox ID="UserPass" TextMode="Password" runat="server" /> </td> <td> <asp:RequiredFieldValidator ID="RequiredFieldValidator2" ControlToValidate="UserPass" ErrorMessage="Cannot be empty." runat="server" /> </td> </tr> <tr> <td> Remember me?</td> <td> <asp:CheckBox ID="Persist" runat="server" /></td> </tr> </table> <asp:Button ID="Submit1" OnClick="Logon_Click" Text="Log On" runat="server" /> <p> <asp:Label ID="Msg" ForeColor="red" runat="server" /> </p> </form> </body> </html> La página contiene controles de servidor ASP.NET recogiendo información sobre el usuario y una casilla de verificación en la que los usuarios pueden hacer clic para conservar sus credenciales de inicio de sesión. El controlador de Click del botón Iniciar sesión contiene código para comprobar la dirección de correo electrónico y la contraseña del usuario utilizando como referencia los valores 18 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 incluidos en el código. (La contraseña es una contraseña segura conteniendo al menos ocho caracteres e incluyendo varios caracteres no alfabéticos). Si las credenciales del usuario son correctas, el código llama al método RedirectFromLoginPage de la clase FormsAuthentication, y le pasa el nombre de usuario y un valor booleano (derivado de la casilla de verificación) indicando si se ha de conservar el “token” de autenticación como una cookie. El método redirige al usuario a la página solicitada originalmente. Si las credenciales del usuario no coinciden, se muestra un mensaje de error. La página importa el espacio de nombres System.Web.Security, conteniendo la clase FormsAuthentication. Crear la página predeterminada Para el ejemplo, se creará una página ASP.NET en la carpeta raíz de la aplicación. Como se especificó en el archivo de configuración la negación a todos los usuarios no autenticados el acceso a los recursos de ASP.NET de la aplicación (incluidos los archivos .aspx, pero no los archivos estáticos como los archivos HTML o los archivos multimedia con imágenes, música etc.), cuando un usuario solicite la página, la autenticación mediante formularios comprobará sus credenciales y, si es necesario, le redirigirá a la página de inicio de sesión. La página que cree también permitirá a los usuarios cerrar la sesión, borrando su vale de autenticación almacenado (cookie). 1. Crear una página ASP.NET denominada Default.aspx en la carpeta raíz de la aplicación. 2. Colocar el siguiente código <%@ Page Language="C#" %> <html> <head> <title>Forms Authentication - Default Page</title> </head> <script runat="server"> void Page_Load(object sender, EventArgs e) { Welcome.Text = "Hello, " + Context.User.Identity.Name; } void Signout_Click(object sender, EventArgs e) { FormsAuthentication.SignOut(); Response.Redirect("Logon.aspx"); } </script> <body> <h3> Using Forms Authentication</h3> 19 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 <asp:Label ID="Welcome" runat="server" /> <form id="Form1" runat="server"> <asp:Button ID="Submit1" OnClick="Signout_Click" Text="Sign Out" runat="server" /><p> </form> </body> </html> La página muestra la identidad autenticada del usuario, establecida por la clase FormsAuthentication y disponible en una página ASP.NET como propiedad Context.User.Identity.Name. El controlador de Click del botón Cerrar sesión contiene código que llama al método SignOut para borrar la identidad del usuario y quitar el “token” de autenticación (cookie). A continuación, redirige al usuario a la página de inicio de sesión. 3 CONFIGURAR PROYECTOS, SOLUCIONES Y CONJUNTOS DE REFERENCIAS: CONJUNTOS LOCALES, CONJUNTOS COMPARTIDOS (GAC), PROYECTOS DE APLICACIONES WEB, SOLUCIONES Introducción a soluciones, proyectos y elementos Visual Studio dispone de dos contenedores para administrar eficazmente los elementos necesarios para el desarrollo, como referencias, conexiones de datos, carpetas y archivos. Estos contenedores se denominan soluciones y proyectos. Asimismo, Visual Studio proporciona carpetas de soluciones para organizar proyectos relacionados en grupos y, a continuación, llevar a cabo acciones en esos grupos de proyectos. El Explorador de soluciones, una interfaz para ver y administrar estos contenedores y sus elementos asociados, forma parte del entorno de desarrollo integrado (IDE). Contenedores: soluciones y proyectos Las soluciones y los proyectos contienen elementos en forma de referencias, conexiones de datos, carpetas y archivos necesarios para crear la aplicación. Una solución puede contener varios proyectos y un proyecto normalmente contiene varios elementos. Estos contenedores permiten sacar partido del IDE mediante las siguientes tareas: Administrar la configuración de la solución en su totalidad o dividida en proyectos individuales Agregar elementos útiles a varios proyectos de la solución o a la solución sin tener que hacer referencia a dichos elementos en cada proyecto. Trabajar en diversos archivos, independientes de soluciones o proyectos Utilizar el Explorador de soluciones para controlar los detalles de la administración de archivos y centrarse al mismo tiempo en los elementos que constituyen la labor de desarrollo. Elementos: archivos, referencias y conexiones de datos Los elementos pueden ser archivos y otras partes del proyecto como referencias, conexiones de datos o carpetas. En el Explorador de soluciones los elementos pueden organizarse de varias formas: En forma de elementos del proyecto, tales como formularios, archivos de código fuente y clases de un proyecto del Explorador de soluciones. La organización y la presentación dependerán de la plantilla de proyecto que se seleccione, así como de cualquier modificación que se realice. En forma de elementos de la solución para archivos aplicando a la solución en su totalidad en la carpeta Elementos de la solución del Explorador de soluciones. 20 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 En forma de varios archivos no asociados a ningún proyecto ni a ninguna solución pudiendo mostrarse en la carpeta Archivos varios. COLOCACIÓN DE ENSAMBLADOS En la mayoría de las aplicaciones .NET Framework, los ensamblados que componen una aplicación se colocan en el directorio de la aplicación, en un subdirectorio de este último o en la caché de ensamblados global (si el ensamblado está compartido). Para reemplazar la ubicación en la que Common Language Runtime busca un ensamblado, se utiliza el elemento <codeBase> en un archivo de configuración. Si el ensamblado no tiene un nombre seguro, la ubicación especificada mediante Elemento <codeBase> se limita al directorio de la aplicación o a un subdirectorio de éste. Si el ensamblado tiene un nombre seguro, Elemento <codeBase> puede especificar cualquier ubicación en el equipo o la red. Se aplican reglas similares a la búsqueda de ensamblados cuando se trabaja con código no administrado o aplicaciones de interoperabilidad COM: si el ensamblado va a compartirse entre varias aplicaciones, debe instalarse en la caché de ensamblados global. Los ensamblados que se utilizan con código no administrado deben exportarse como biblioteca de tipos y registrarse. Los ensamblados utilizados por la interoperabilidad COM deben registrarse en el catálogo, aunque, en algunos casos, este registro es automático. CACHÉ DE ENSAMBLADOS GLOBAL Cada equipo donde se instala Common Language Runtime CLR tiene una memoria caché de código denominada caché de ensamblados global. La caché de ensamblados global almacena los ensamblados designados específicamente para ser compartidos por varias aplicaciones del equipo. Se recomienda compartir los ensamblados mediante su instalación en la caché de ensamblados global sólo cuando sea necesario. Como norma general, se deben mantener las dependencias de los ensamblados privadas y colocar los ensamblados en el directorio de la aplicación, a menos que sea explícitamente necesario compartir un ensamblado en concreto. Además, no es necesario instalar los ensamblados en la caché de ensamblados global para obtener acceso a ellos el código de interoperabilidad COM o el código no administrado. Existen escenarios donde no se desea instalar un ensamblado en la caché de ensamblados global. Si se coloca uno de los ensamblados componiendo una aplicación en la memoria caché de ensamblados global, no se podrá replicar ni instalar la aplicación utilizando el comando xcopy para copiar el directorio de la aplicación. También se debe mover el ensamblado en la caché de ensamblados global. Existen varias formas de implementar un ensamblado en la caché de ensamblados global: Usar un instalador diseñado para funcionar con la caché de ensamblados global. Es la opción preferida para instalar ensamblados en la caché de ensamblados global. Utilizar la herramienta de desarrollador Caché de ensamblados global (Gacutil.exe), suministrada con Kit de desarrollo de software de Windows (SDK). Usar el Explorador de Windows para incluir ensamblados en la caché. En escenarios de implementación, se recomienda utilizar Windows Installer 2.0 para instalar los ensamblados en la caché de ensamblados global. Utilizar el Explorador de Windows o la herramienta Caché de ensamblados global sólo en escenarios de programación, porque no proporcionan funciones de recuento de referencias de ensamblados y otras funciones que se incluyen con Windows Installer. Con frecuencia, los administradores protegen el directorio systemroot con una lista de control de acceso (ACL) para controlar el acceso de escritura y ejecución. Puesto que la caché de ensamblados global está instalada en un subdirectorio del directorio systemroot, hereda la lista (ACL) de dicho directorio. Es recomendable que sólo puedan eliminar archivos de la caché de ensamblados global los usuarios que tengan privilegios de administrador. Los ensamblados implementados en la caché de ensamblados global deben tener nombres seguros. Cuando se agrega un ensamblado a la caché de ensamblados global, se realizan comprobaciones de integridad de todos los archivos que componen el ensamblado. La caché realiza estas comprobaciones de integridad para garantizar que no se ha manipulado ningún ensamblado, por ejemplo, cuando se ha modificado un archivo pero el manifiesto no refleja el cambio. 21 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 4 CONFIGURAR EL ESTADO DE LA SESIÓN UTILIZANDO MICROSOFT SQL SERVER, STATE SERVER O INPROC: CONFIGURACIÓN DEL TIEMPO DE ESPERA; SESIONES SIN COOKIES ESTADO DE SESIÓN DE ASP.NET El estado de sesión de ASP.NET permite almacenar y recuperar los valores de un usuario cuando el usuario explora diferentes páginas ASP.NET conformando una aplicación Web. HTTP es un protocolo sin estado, es decir, el servidor Web trata cada solicitud HTTP de página como solicitud independiente; de forma predeterminada, el servidor no retiene información alguna sobre los valores de las variables que se utilizan durante las solicitudes anteriores. En consecuencia, la creación de aplicaciones Web que necesitan mantener la información de estado entre las solicitudes (aplicaciones que implementan carros de la compra, desplazamiento de datos, etc.) puede resultar complicada. El estado de sesión de ASP.NET identifica las solicitudes recibidas desde el mismo explorador durante un período limitado de tiempo como una sesión y proporciona la capacidad de conservar los valores de las variables durante la duración de esa sesión. El estado de sesión de ASP.NET se habilita de forma predeterminada en todas las aplicaciones ASP.NET. Las variables de estado de sesión de ASP.NET se definen con facilidad y se recuperan mediante la propiedad Session, que almacena los valores de las variables de la sesión como una colección indizada por nombre. Por ejemplo, mediante el ejemplo de código siguiente se crean las variables de sesión FirstName y LastName para representar el nombre y el apellido de un usuario, y las variables se establecen en los valores recuperados de los controles TextBox. Session["FirstName"] = FirstNameTextBox.Text; Session["LastName"] = LastNameTextBox.Text; De forma predeterminada, ASP.NET almacena la información de la sesión en el espacio de memoria de la aplicación ASP.NET. Si se desea, puede almacenarse la información de la sesión mediante un servicio independiente para que no se pierda si se reinicia la aplicación ASP.NET, en un servidor SQL Server, a fin de que la información de la sesión esté disponible para varios servidores Web en una batería de servidores Web (y también se mantenga si se reinicia la aplicación ASP.NET), o en un almacén de datos personalizado. ASP.NET proporciona también algunas otras opciones para conservar los datos en una aplicación además del estado de sesión. MODOS DE ESTADO DE SESIÓN El estado de sesión de ASP.NET es compatible con distintas opciones de almacenamiento de los datos de la sesión. Cada opción se identifica mediante un valor en la enumeración SessionStateMode. En la lista siguiente se describen los modos de estado de sesión disponibles: Modo InProc, almacena el estado de sesión en memoria en el servidor Web. Éste es el valor predeterminado. Modo StateServer, almacena el estado de sesión en un proceso distinto denominado "servicio de estado de ASP.NET". Este modo garantiza que el estado de sesión se mantiene si se reinicia la aplicación Web y que esté disponible también para varios servidores Web en una batería de servidores Web. Modo SQLServer, almacena el estado de sesión en una base de datos de SQL Server. Este modo garantiza que el estado de sesión se mantiene si se reinicia la aplicación Web y que esté disponible también para varios servidores Web en una batería de servidores Web. Modo Custom, permite especificar un proveedor de almacenamiento personalizado. Modo Off, deshabilita el estado de sesión. Se puede especificar el modo para el estado de sesión de ASP.NET asignando valores de enumeración SessionStateMode al atributo mode del elemento sessionState en el archivo Web.config de la aplicación. Todos los modos, excepto InProc y Off, requieren parámetros adicionales, como valores de cadena de conexión. Para ver el estado de sesión seleccionado actualmente se consulta el valor de la propiedad System.Web.SessionState.HttpSessionState.Mode. 22 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 MODO EN PROCESO “IN PROC” En proceso es el modo de estado de sesión predeterminado y se especifica mediante el valor InProc de la enumeración SessionStateMode. El modo En proceso almacena valores de estado de sesión y variables en memoria en el servidor Web local. Es el único modo que admite el evento Session_OnEnd. Si se habilita el modo Hospedaje multiproceso en un único equipo y para ello establece el atributo webGarden en true en el elemento processModel del archivo Web.config de la aplicación, no se debe utilizar el modo de estado de sesión InProc. De hacerse, se puede producir una pérdida de datos si diferentes procesos de trabajo atienden solicitudes distintas para la misma sesión. MODO SERVIDOR DE ESTADO “STATE SERVER” El modo StateServer almacena estado de sesión en un proceso, al que se denomina servicio de estado de ASP.NET, independiente del proceso de trabajo ASP.NET o grupo de aplicaciones IIS. Con este modo se garantiza que el estado de sesión se mantiene si se reinicia la aplicación Web y que esté disponible también para varios servidores Web en una batería de servidores Web. Para utilizar el modo StateServer, debe asegurarse de que el servicio de estado de ASP.NET se está ejecutando en el servidor remoto utilizado como almacén de la sesión. El servicio de estado de ASP.NET se instala como un servicio cuando se instalan ASP.NET y .NET Framework. El servicio de estado de ASP.NET se instala en la ubicación siguiente: raízDelSistema\Microsoft.NET\Framework\númeroDeVersión\aspnet_state.exe Para configurar una aplicación ASP.NET para utilizar el modo StateServer, en el archivo Web.config de la aplicación haga lo siguiente: Establecer el atributo mode del elemento sessionState en StateServer. Establecer el atributo stateConnectionString en tcpip=nombreDeServidor:42424. Para mejorar la seguridad de la aplicación al utilizar el modo StateServer, se recomienda proteger el valor stateConnectionString cifrando la sección sessionState en el archivo de configuración. En el ejemplo siguiente se muestra una opción de configuración para el modo StateServer donde el estado de sesión se almacena en un equipo remoto denominado SampleStateServer: <configuration> <system.web> <sessionState mode="StateServer" stateConnectionString="tcpip=SampleStateServer:42424" cookieless="false" timeout="20"/> </system.web> </configuration> Los objetos almacenados en el estado de sesión deben ser serializables si el modo está establecido en StateServer. Para utilizar el modo StateServer en una batería de servidores Web, debe tener las mismas claves de cifrado especificadas en el elemento machineKey de la configuración Web para todas las aplicaciones formando parte de la batería de servidores. MODO SQL SERVER El modo SQLServer almacena el estado de sesión en una base de datos de SQL Server. Con este modo se garantiza que el estado de sesión se mantiene si se reinicia la aplicación Web y que esté disponible también para varios servidores Web en una batería de servidores Web. 23 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Los objetos que están almacenados en el estado de sesión deben ser serializables si el modo utilizado es SQL Server. Para utilizar el modo SQLServer, primero debe estar seguro de que la base de datos del estado de sesión de ASP.NET esté instalada en SQL Server. Puede instalar la base de datos del estado de sesión de ASP.NET mediante la herramienta Aspnet_regsql.exe. Para configurar una aplicación ASP.NET para utilizar el modo SQLServer, en el archivo Web.config: Establecer el atributo mode del elemento sessionState en SQLServer. Establecer el atributo sqlConnectionString en una cadena de conexión para su base de datos de SQL Server. Para mejorar la seguridad de la aplicación al utilizar el modo SQLServer, se recomienda proteger el valor sqlConnectionString cifrando la sección sessionState de su archivo de configuración.. En el ejemplo siguiente se muestra una opción de configuración para el modo SQLServer donde el estado de sesión se almacena en un servidor SQL Server denominado "BDGALA": <configuration> <system.web> <sessionState mode="SQLServer" sqlConnectionString="Integrated Security=SSPI;data source=BDGALA;" /> </system.web> </configuration> Si especifica una conexión de confianza con el SQL Server en el archivo de configuración utilizando el atributo sqlConnectionString del elemento sessionState, el SessionStateModule conectará con el SQL Server mediante la seguridad integrada de SQL Server. La conexión se realizará utilizando la identidad del proceso en ASP.NET o las credenciales del usuario proporcionadas para el elemento de configuración de identidad, si existen. Se puede especificar utilizar la identidad suplantada por IIS definiendo <identity impersonate="true" /> y establecer el atributo useHostingIdentity del elemento de configuración sessionState en false. Para configurar el modo SQLServer para una batería de servidores Web, en el archivo de configuración para cada servidor Web, se establece el atributo sqlConnectionString del elemento sessionState para señalar a la misma base de datos SQL Server. La ruta de acceso de la aplicación ASP.NET en la metabase de IIS debe ser idéntica en todos los servidores Web que compartan el estado de sesión en la base de datos de SQL Server. Instalar la base de datos de estado de sesión mediante la herramienta Aspnet_regsql.exe Para instalar la base de datos de estado de sesión en SQL Server, ejecutar la herramienta Aspnet_regsql.exe que se encuentra en la carpeta raízDelSistema\Microsoft.NET\Framework\númeroDeVersión del servidor Web. Se proporciona la información siguiente con el comando: El nombre de la instancia de SQL Server, mediante la opción -S. Las credenciales de inicio de sesión para una cuenta que tiene el permiso para crear una base de datos en SQL Server. Seleccionar la opción -E para utilizar el usuario que tiene la sesión actual abierta o utilizar la opción -U para especificar un identificador de usuario junto con la opción -P para especificar una contraseña. La opción de la línea de comandos -ssadd para agregar la base de datos de estado de sesión. De forma predeterminada, no se puede utilizar la herramienta Aspnet_regsql.exe para instalar la base de datos de estado de sesión en SQL Server Express Edition. Para ejecutar la herramienta Aspnet_regsql.exe para instalar una base de datos SQL Server Express Edition, primero se debe habilitar la opción Agent XPs SQL Server mediante comandos de T-SQL como los siguientes: EXECUTE sp_configure 'show advanced options', 1 24 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 RECONFIGURE WITH OVERRIDE GO EXECUTE sp_configure 'Agent XPs', 1 RECONFIGURE WITH OVERRIDE GO EXECUTE sp_configure 'show advanced options', 0 RECONFIGURE WITH OVERRIDE GO Se debe ejecutar estos comandos T-SQL para cualquier instancia de SQL Server Express Edition dónde se deshabilita la opción Agent XPs. De forma predeterminada, la herramienta Aspnet_regsql.exe creará una base de datos denominada ASPState que contiene procedimientos almacenados que admiten el modo SQLServer. Los datos de la sesión se almacenan de forma predeterminada en la base de datos tempdb. Si se desea, puede utilizar la opción -sstype para cambiar la ubicación de almacenamiento de los datos de la sesión. A continuación se especifica los valores posibles para la opción -sstype: t : Almacena los datos de la sesión en la base de datos tempdb de SQL Server. Éste es el valor predeterminado. Si almacena los datos de la sesión en esta base de datos, los datos de la sesión se perderán si se reinicia SQL Server. p : Almacena los datos de la sesión en la base de datos ASPState en lugar de en la base de datos tempdb. c : Almacena los datos de la sesión en una base de datos personalizada. Si especifica la opción c, también debe incluir el nombre de la base de datos personalizada utilizando la opción -d. Por ejemplo, el siguiente comando crea una base de datos llamada ASPState en una instancia de SQL Server denominada "BDGALA" y especifica que los datos de la sesión también se almacenan en la base de datos ASPState: aspnet_regsql.exe -S BDGALA -E -ssadd -sstype p Si se va a ejecutar ASP.NET 1.0 o ASP.NET 1.1, no se puede utilizar la herramienta Aspnet_regsql.exe para configurar ASP.NET para almacenar el estado de sesión en una base de datos persistente de SQL Server. Sin embargo, se puede obtener secuencias de comandos para almacenar estados de sesión en una base de datos persistente. En el modo SQLServer, se puede configurar varios equipos ejecutando SQL Server para funcionar como un clúster de conmutación por error, es decir, dos o más equipos idénticos ejecutándo SQL Server y almacenando datos para una sola base de datos. Si se produce un error en un equipo que ejecuta SQL Server, otro servidor del clúster asume el control y atiende las solicitudes sin que se pierdan los datos de la sesión. Para configurar el modo SQL Server para un clúster de conmutación por error, debe especificar sstype p cuando ejecute la herramienta Aspnet_regsql.exe de modo que los datos del estado de sesión se almacenan en la base de datos ASPState en vez de en la base de datos tempdb. Los clústeres de servidores SQL Server no permiten almacenar el estado de sesión en la base de datos tempdb. MODO PERSONALIZADO El modo Custom especifica que desea almacenar datos del estado de sesión mediante un proveedor del almacén de estados de sesión personalizado. Cuando se configura la aplicación de ASP.NET con una propiedad Mode de Custom, se debe especificar el tipo de proveedor de almacenes de estados de sesión mediante el subelemento providers del elemento de configuración sessionState. El tipo de proveedor se especifica utilizando un subelemento add e incluyendo tanto un atributo type que especifique el nombre del tipo de proveedor como un atributo name que especifique el nombre de la instancia del proveedor. El nombre de la instancia del proveedor se proporciona al atributo customProvider del elemento de sessionState para configurar el estado de sesión de ASP.NET de modo que utilice esa instancia de proveedor para almacenar y recuperar los datos de la sesión. 25 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 En el ejemplo siguiente se muestran elementos de un archivo Web.config donde se especifica que el estado de sesión de ASP.NET utiliza un proveedor de almacenes de estados de sesión personalizado. <configuration> <connectionStrings> <add name="OdbcSessionServices" connectionString="DSN=SessionState;" /> </connectionStrings> <system.web> <sessionState mode="Custom" customProvider="OdbcSessionProvider"> <providers> <add name="OdbcSessionProvider" type="Samples.AspNet.Session.OdbcSessionStateStore" connectionStringName="OdbcSessionServices" writeExceptionsToEventLog="false" /> </providers> </sessionState> </system.web> </configuration> Un proveedor de almacenes de estados de sesión personalizados obtendrá acceso a cualquier recurso protegido, como por ejemplo SQL Server, mediante la identificación del proceso ASP.NET o las credenciales de usuario proporcionadas al elemento de configuración identity, si existieran. Se puede especificar utilizar la identidad suplantada por IIS definiendo <identity impersonate="true" /> y estableciendo el atributo useHostingIdentity del elemento de configuración sessionState en false. 5 PUBLICAR APLICACIONES WEB: SISTEMA DE ARCHIVOS O HTTP DE VISUAL STUDIO Lo nuevo en la publicación de sitios Web en Visual Studio En este tema se describen las nuevas características de Visual Studio para implementar, o publicar, sitios Web en un servidor de ensayo o de producción. 26 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 A partir de Visual Studio 2005, el proceso de trasladar un sitio Web en desarrollo a un servidor de ensayo o de producción es mucho más fácil que con las versiones anteriores. En versiones anteriores, todas las partes del código del sitio Web se generaban en un ensamblado único. A continuación, el ensamblado generado, junto con los archivos .aspx, el archivo Web.config y otros archivos que no son de código se implementaban en el servidor de destino. Las formas más habituales de implementar los archivos eran las siguientes: usar la utilidad Copiar proyecto, para lo que el servidor de destino tenía que estar en una red de área local; usar las Extensiones de servidor de FrontPage de Microsoft, o crear un proyecto de instalación para generar un archivo de instalación (.msi). En la versión actual de Visual Studio, se puede implementar un proyecto utilizando las herramientas siguientes: La herramienta Copiar sitio Web, que copia directamente el sitio Web actual en el servidor de destino. La utilidad Publicar sitio Web, que compila el sitio Web en un conjunto de archivos ejecutables. A continuación, se puede copiar los archivos en el servidor de destino, utilizando el método que desee. La utilidad de publicación de sitios Web no está disponible en Visual Web Developer Express. Estas herramientas no requieren configuración especial en el servidor de destino, como sucede con las Extensiones de servidor de FrontPage. Además de crear el sitio Web e implementarlo en un servidor de destino, también puede crear un sitio Web del Protocolo de transferencia de archivos (FTP). En ese caso, los archivos se crean y editan directamente en el servidor de destino, lo que representa una forma muy cómoda de trabajar con un sitio Web en un servidor alojado. Copiar sitios Web La herramienta Copiar sitio Web es parecida a una utilidad de FTP: se puede abrir una carpeta en un servidor de destino y, a continuación, cargar y descargar archivos del sitio Web actual en el sitio Web de destino, y viceversa. La herramienta Copiar sitio Web ofrece las mejoras siguientes respecto a la utilidad Copiar proyecto de las versiones anteriores de Visual Studio: No es necesario compilar los archivos en el sitio Web antes de copiarlos en el servidor de destino. En lugar de ello, sólo se debe copiar los archivos de código fuente, incluidos los archivos .aspx y archivos de clase, en el servidor de destino. Igual que sucede con cualquier sitio Web ASP.NET, las páginas Web se compilan dinámicamente cuando se solicita. La herramienta Copiar sitio Web permite abrir y copiar archivos desde cualquier sitio Web compatible con Visual Studio, incluidos los de Servicios de Internet Information Server (IIS), IIS remoto y FTP. No es necesario que el servidor de destino tenga las Extensiones de servidor de FrontPage. Además de copiar un proyecto en un servidor de destino, la herramienta Copiar sitio Web se puede utilizar para realizar otras tareas. Es compatible con una característica de sincronización que examina los archivos de los dos sitios Web y, automáticamente, garantiza que las versiones de los archivos están actualizadas en ambos sitios. Antes de copiar los archivos de aplicación, la herramienta Copiar sitio Web coloca un archivo denominado App_offline.htm en el directorio raíz del sitio Web de destino. Mientras exista el archivo App_offline.htm, todas las solicitudes que se hagan al sitio Web se redirigirán a este archivo, que muestra un mensaje descriptivo para indicar a los clientes que se está actualizando el sitio Web. Una vez que se han copiado todos los archivos del sitio Web, la herramienta Copiar sitio Web elimina el archivo App_offline.htm del sitio Web de destino. Debe tener la versión 2.0 de .NET Framework instalada en el servidor de destino para que las páginas Web se ejecuten como se espera. Si el servidor de destino es un servidor FTP, se pueden abrir y editar los archivos en el servidor creando un sitio Web FTP. También se pueden administrar el sitio de destino la herramienta Administración de sitios Web. Compilar sitios Web La utilidad de publicación de sitios Web realiza la compilación previa del contenido del sitio Web, tanto las páginas Web (archivos .aspx) como el código, y copia el resultado en el directorio o ubicación de servidor especificada. Se puede publicar el contenido directamente como parte del proceso de compilación previa, o realizar la compilación previa localmente y, después, copiar los archivos. La utilidad de publicación de sitios Web compila el sitio Web y elimina el código fuente de los archivos, y sólo deja los 27 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 archivos de código auxiliar de las páginas y los ensamblados compilados. Cuando los usuarios solicitan las páginas, ASP.NET da servicio a la solicitud desde los ensamblados precompilados. El proceso de compilación previa de la utilidad de publicación de sitios Web no es igual que el de las versiones anteriores de Visual Studio, como se describe a continuación: En Visual Studio .NET 2003, sólo se compilaban los archivos de código. En la utilidad de publicación de sitios Web, se puede compilar opcionalmente el marcado de los archivos .aspx junto con el código de página y cualquier otro archivo ejecutable. En Visual Studio .NET 2003, todo el código se compilaba en un ensamblado único. En el nuevo modelo, todos los archivos de clase independientes se compilan en un ensamblado. Sin embargo, las pagina y el código correspondiente (de un solo archivo o subyacente) se compilan en ensamblados individuales. En la utilidad de publicación de sitios Web, el código fuente se quita del sitio Web, incluido, si se desea, el marcado de los archivos .aspx. Los archivos .aspx siguen estando presentes, pero sólo contienen punteros que indican las versiones compiladas de las páginas. De esta forma, el contenido queda más protegido y resulta más difícil que otros usuarios tengan acceso al código fuente del sitio. En consecuencia, el sitio Web tiene las mismas ventajas que los resultados creados con versiones anteriores de Visual Studio, con mayor rapidez de respuesta inicial de las páginas y compilación previa que contribuye a descubrir errores del código en tiempo de compilación. La utilidad de publicación de sitios Web también compila archivos que no son de código, por ejemplo el archivo Web.config. Así, sirve de ayuda para encontrar errores de compilación y problemas en el archivo de configuración. Copiar sitios Web con la herramienta Copiar sitio Web La herramienta Copiar sitio Web permite copiar los archivos entre el sitio Web actual y otro sitio. La herramienta Copiar sitio Web es similar a una utilidad FTP, pero se diferencia en lo siguiente: Permite conectar y copiar archivos entre todos los tipos de sitios Web creados en Visual Studio, incluidos los sitos Web locales, los sitios Web de ISS, los sitios Web remotos (FrontPage) y los sitios FTP. Admite una característica de sincronización, que examina los archivos en ambos sitios y se asegura de que todos los archivos están actualizados. Se puede utilizar la herramienta Copiar sitio Web para mover archivos de su equipo local a un servidor de ensayo o a un servidor de producción. La herramienta Copiar sitio Web es especialmente útil en situaciones donde no puede abrir los archivos desde el sitio remoto para editarlos. Se puede utilizar la herramienta Copiar sitio Web para copiar archivos en el equipo local, editarlos y copiarlos otra vez en el sitio remoto. También se puede utilizar la herramienta para copiar archivos de un servidor de ensayo a un servidor de producción cuando haya terminado su proceso de desarrollo. Si copia una aplicación que contiene una referencia a un componente personalizado registrado en la GAC, el componente no se copiará con la aplicación. Sitios de origen y sitios remotos La herramienta Copiar sitio Web copia archivos entre un sitio de origen y un sitio remoto. Estos términos se utilizan para distinguir los dos sitios con los que trabaja la herramienta. Los términos se utilizan con significados específicos: Sitio de origen El sitio de origen es el sitio que tiene actualmente abierto en Visual Studio. Sitio remoto El sitio remoto es el sitio en el que desea copiar archivos. Un sitio remoto puede ser una ubicación en otro equipo al que puede tener acceso utilizando las Extensiones de servidor de FrontPage o FTP. En estos casos, el sitio es literalmente remoto. Sin embargo, el sitio remoto también puede ser otro sitio en su propio equipo. Por ejemplo, se puede publicar desde un sitio Web del sistema de archivos de su equipo en un sitio Web de ISS local que está también en su equipo. En este caso, aunque el sitio es local en su equipo, es el sitio remoto a efectos de la herramienta Copiar sitio Web. Observe que el sitio de origen no es necesariamente el origen del que se copia. Se puede copiar del sitio remoto al sitio de origen. Sincronizar los sitios Además de copiar archivos, la herramienta Copiar sitio Web permite sincronizar los sitios. Al sincronizar, se examinan los archivos de los sitios local y remoto y se asegura que todos los archivos de ambos sitios están actualizados. Por ejemplo, si un archivo en un 28 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 sitio remoto es más actual que la versión que hay del mismo archivo en el sitio local, al sincronizar los archivos se copia el archivo del sitio remoto en el sitio local. La herramienta Copiar sitio Web no combina archivos que tienen el mismo nombre pero diferente contenido. En ese caso, la sincronización le da la oportunidad de especificar qué versión del archivo desea mantener. La sincronización hace que la herramienta resulte adecuada para un entorno de varios desarrolladores en el que éstos mantienen copias del sitio Web en sus equipos locales. Cada desarrollador puede copiar los últimos cambios en un servidor remoto compartido y a la vez actualizar su equipo local con los archivos que han modificado otros desarrolladores. Un desarrollador que sea nuevo en un proyecto puede también obtener rápidamente copias de todos los archivos de un sitio Web mediante la creación de un sitio Web local en su propio equipo y la sincronización con el sitio del servidor compartido. Estado de los archivos Para sincronizar archivos, la herramienta Copiar sitio Web necesita información sobre el estado de los archivos en ambos sitios. Por consiguiente, la herramienta mantiene información que consta de las marcas de hora de los archivos más la información adicional que se necesita para realizar la sincronización. Por ejemplo, la herramienta mantiene una lista de cuándo fue la última vez que se modificaron los archivos, lo que le permite a la herramienta determinar, por ejemplo, si se ha eliminado un archivo. Cuando se conecta a un sitio (o se actualiza), la herramienta compara las marcas de hora de los archivos en ambos sitios así como la información almacenada sobre ambos sitios y se crea un informe del estado de cada archivo. A continuación se muestra el estado de los archivos. Sin cambios El archivo no ha cambiado desde la última vez que se copió. Modificado El archivo tiene una marca de hora más reciente que la marca de hora que se tomó cuando se copió el archivo por última vez. Nuevo Se ha agregado el archivo desde la última vez que se copió el sitio. Eliminado Se ha eliminado el archivo desde la última vez que se copió el sitio. Si selecciona Mostrar archivos eliminados en la herramienta Copiar sitio Web, en la ventana se muestra una entrada para el archivo. 6 CONFIGURAR CONJUNTOS DE APLICACIONES Una de las características de IIS a partir de la versión 6.0 es el “Application Pool”, conjunto de aplicaciones. Esta facilidad pude ser utilizada para aislar las aplicaciones WEB ASP.Net y de esta manera se incrementa la confiablidad de las aplicaciones. El conjunto de aplicaciones también afecta en el tipo de identidad que es utilizada para ejecutar las aplicaciones ASP.Net. Los conjuntos de aplicaciones se crean en IIS y estos son configurados para ser ejecutados utilizando las credenciales de una cuenta de usuario. ¿Qué es un conjunto de aplicaciones? Un conjunto de aplicaciones puede contener una o más aplicaciones y permite configurar un nivel de aislamiento entre diferentes aplicaciones WEB. Por ejemplo, se podrían aislar todas las aplicaciones web para ser ejecutadas en el mismo equipo; para lograr esto se puede crear un grupo de aplicaciones para cada aplicación web y colocarlas todas en el correspondiente grupo de aplicaciones. Como cada grupo de aplicaciones corre sus propios procesos de trabajos, errores en un grupo de aplicaciones no afectará a las aplicaciones ejecutándose en otro grupo de aplicaciones. La implantación de aplicaciones en grupos de aplicaciones es la principal ventaja de ejecutar II 6.0 en el modo de aislamiento de procesos de trabajo porque se pueden parametrizar los grupos de aplicaciones para lograr el nivel de aislamiento requerido. Cuando se configuran los grupos de aplicaciones buscando lograr la disponibilidad óptima, también deben ser considerados los criterios de seguridad. Por ejemplo, se pueden crear grupos de aplicaciones separados para aplicaciones que requieran un alto nivel de seguridad mientras que todas aquellas aplicaciones no necesitando este nivel de seguridad pueden ser colocadas en otro grupo de aplicaciones. Crear un grupo de aplicaciones Este proceso se realiza en el administrador de IIS. Existen dos opciones para crear un grupo de aplicaciones: 29 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Crear desde cero un nuevo grupo de aplicaciones Crear un grupo de aplicaciones importando los parámetros de configuración desde un archivo XML externo Para crear un grupo de aplicaciones desde cero, se pulsa botón derecho en el nodo “Application Pools” del árbol y se coloca el nombre deseado para el grupo. Cuando se crea una nueva aplicación, existe la opción de heredar los parámetros de un grupo de aplicaciones existentes. Por ejemplo si se requiere heredar del grupo DefaultAppPool, se escoge la opción utilizar un grupo de aplicaciones existentes como plantilla. Una vez creado el grupo de aplicaciones, los parámetros pueden ser almacenados en un archivo XML externo. Se selecciona el grupo de aplicaciones, Todasl Las tareas, Guardar archivo de Configuración. Configurando la identidad para las Aplicaciones Web ASP.NET En versiones previas de IIS, los procesos de trabajo corrían como LocalSystem, una cuenta con bastante poder y con privilegios de administrador de sistemas en el servidor. LocalSystem tiene acceso casi total a todos los recursos del sistema de operación y esto ocasionaba inconvenientes de seguridad. A partir de IIS 6.0 se puede parametrizar la identidad del proceso de trabajo al nivel del grupo de aplicaciones. La identidad de un grupo de aplicaciones es la cuenta donde el proceso de trabajo del grupo de aplicaciones se está ejecutando. Por defecto, el grupo de aplicaciones opera sobre la cuenta NetworkService, la cual tiene derechos de un usuario de bajo nivel de acceso. La cuenta NetworkService tiene los siguientes siete privilegios: Ajuste de cuotas de memoria para un proceso Generar auditorias de seguridad Log on como servicio Reemplazo de ficha (token) a nivel de proceso Impersonar a un cliente después de la autorización Permitir acceso local Acceso al computador desde la red Al ejecutar el proceso de trabajo con una cuenta de bajos privilegios como NetworkService, se puede reducer la vulnerabilidad del sistema. Sin embargo, empleando el IIS manager, se puede configurar el grupo de aplicaciones para ser ejecutado en cualquiera de las siguientes cuentas definidas: NetworkService LocalSystem LocalService 7 COMPILAR UNA APLICACIÓN UTILIZANDO VISUAL STUDIO O HERRAMIENTAS DE LÍNEA DE COMANDO: ASPNET_COMPILER.EXE, COMPILACIÓN JUST-IN-TIME (JIT), ASPNET_MERGE.EXE HERRAMIENTA DE COMPILACIÓN DE ASP.NET (Aspnet_compiler.exe) La herramienta de compilación de ASP.NET (Aspnet_compiler.exe) hace posible la compilación de una aplicación Web ASP.NET, en el propio lugar donde se encuentra o para implementarse en una ubicación de destino como un servidor de producción. La compilación en el mismo lugar donde se encuentra ayuda al rendimiento de la aplicación ya que los usuarios finales no sufren ningún retraso en la primera solicitud que se hace a la aplicación mientras se compila la aplicación en cuestión. La compilación para implementación se puede llevar a cabo de una de las dos formas siguientes: una que consiste en quitar todos los archivos de código fuente (como archivos de marcado y archivos de código subyacente), o bien otra que retiene los archivos de marcado. La herramienta de compilación de ASP.NET no está disponible en versiones de ASP.NET anteriores a la 2.0. 30 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 La sintáxis de la herramienta es la siguiente: aspnet_compiler [-?] [-m metabasePath | -v virtualPath [-p physicalPath]] [[-u] [-f] [-d] [-fixednames] targetDir] [-c] [-errorstack] [-nologo] [-keyfile file | -keycontainer container ] [-aptca] [-delaysign]] Opción Descripción -m metabasePath Especifica la ruta completa de la metabase de IIS de la aplicación que se va a compilar. La metabase de IIS es un almacén de información de carácter jerárquico que se utiliza para configurar IIS. Por ejemplo, la ruta de acceso de la metabase al sitio Web de IIS predeterminado es LM/W3SVC/1/ROOT. Esta opción no se puede combinar con las opciones -v o -p. -v virtualPath Especifica la ruta de acceso virtual de la aplicación que se va a compilar. Si también se especifica -p, el valor del parámetro physicalPath acompañante se utiliza para ubicar la aplicación que se va a compilar. En caso contrario, se utiliza la metabase de IIS y la herramienta da por hecho que los archivos de código fuente se encuentran en el sitio Web predeterminado (especificado en el nodo de la metabase LM/W3SVC/1/ROOT). Esta opción no se puede combinar con la opción -m. -p physicalPath Especifica la ruta completa de acceso a la red o la ruta de acceso local al disco del directorio raíz que contiene la aplicación que se va a compilar. Si no se especifica -p, la metabase de IIS se utiliza para buscar el directorio. Esta opción se debe combinar con la opción -v y no se puede combinar con la opción -m. -u Especifica que Aspnet_compiler.exe debería crear una aplicación precompilada que permita llevar a cabo actualizaciones subsiguientes de contenido como páginas .aspx. Si se omite esta opción, la aplicación resultante sólo contendrá archivos compilados y no se podrá actualizar en el servidor de implementación. Sólo se podrá actualizar la aplicación cambiando los archivos de marcado de código fuente y volviendo a realizar una nueva compilación. Debe incluirse el parámetro targetDir. -f Especifica que la herramienta debería sobrescribir los archivos existentes en el directorio targetDir y sus subdirectorios. -d Reemplaza los valores de configuración definidos en los archivos de configuración de código fuente de la aplicación para obligar a a que se incluya información de depuración en la aplicación compilada. En caso 31 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 contrario, no se emite ningún resultado de depuración. No se puede utilizar la opción -d para la compilación en contexto; la compilación en contexto admite los valores de configuración de las opciones de depuración. targetDir Ruta de acceso a la red o la ruta de acceso del disco local al directorio raíz que contendrá la aplicación compilada. Si no se incluye el parámetro targetDir, la aplicación se compila en el lugar donde se encuentra. -c Especifica que se debería volver a generar por completo la aplicación que se va a compilar. Se vuelven a compilar componentes ya compilados. Si se omite esta opción, la herramienta genera sólo aquellas partes de la aplicación que se hayan modificado desde la última vez que se realizó la compilación. -errorstack Especifica que la herramienta debería incluir información del seguimiento de la pila si se produce un error a la hora de compilar la aplicación. -keyfile file Especifica que AssemblyKeyFileAttribute, que indica el nombre del archivo que contiene el par de claves pública y privada utilizado para generar un nombre seguro, debería aplicarse al ensamblado compilado. Esta opción debe combinarse con la opción -aptca. Si el atributo ya se aplica al ensamblado en archivos de código, Aspnet_compiler.exe produce una excepción. - Especifica que AssemblyKeyNameAttribute , que indica el nombre del archivo que contiene el par de keycontainer container claves pública y privada utilizado para generar un nombre seguro, debería aplicarse al ensamblado compilado. Esta opción debe combinarse con la opción -aptca. Si el atributo ya se aplica al ensamblado en archivos de código, Aspnet_compiler.exe produce una excepción. -aptca Especifica que AllowPartiallyTrustedCallersAttribute , que permite el acceso parcial de los llamadores de plena confianza a un ensamblado, se debería aplicar al ensamblado de nombre seguro que Aspnet_compiler.exe genera. Esta opción no se puede combinar con la opción -keyfile o -keycontainer. Si el atributo ya se aplica al ensamblado en archivos de código, Aspnet_compiler.exe produce una excepción. -delaysign Especifica que AssemblyDelaySignAttribute , que indica que un ensamblado sólo se debería firmar con el símbolo (token) de clave pública y no con el par de claves pública/privada, se debería aplicar al ensamblado generado. Esta opción no se puede combinar con la opción -keyfile o -keycontainer. Si el atributo ya se aplica al ensamblado en archivos de código, Aspnet_compiler.exe produce una excepción. -fixednames Especifica que se debería generar un ensamblado para cada página de la aplicación. En el nombre de cada ensamblado figura la ruta de acceso virtual de la página original a menos que el nombre exceda el límite del sistema operativo para los nombres de archivo, en cuyo caso se genera código hash y se utiliza para el nombre del ensamblado. No se puede utilizar la opción -fixednames para la compilación en contexto; la compilación en contexto admite los valores de configuración del modo de procesamiento por lotes de la compilación. -nologo Suprime el mensaje de copyright. 32 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 -? Muestra la sintaxis de comandos y opciones para la herramienta. La herramienta de compilación de ASP.NET se puede utilizar de dos formas generales: para una compilación en contexto y para una complicación para implementación, donde se especifica un directorio de destino de resultados. En las secciones siguientes se describen los siguientes escenarios. Compilar una aplicación en contexto La herramienta de compilación de ASP.NET puede compilar una aplicación en contexto, es decir, reproduce el comportamiento de realización de varias solicitudes en la aplicación, así como el hecho de que se produzca una compilación de forma regular. Los usuarios de un sitio precompilado no experimentarán ningún retraso que se haya producido durante la compilación de la página en primera solicitud. Al precompilar un sitio en contexto, se aplican los siguientes elementos: El sitio retiene sus archivos y la estructura de directorios. Es necesario contar con compiladores para todos los lenguajes de programación utilizados por el sitio en el servidor. Si se produce algún error en algún archivo durante el proceso de compilación, también aparecerá un error que afectará a todo el sitio relacionado con la compilación. También será posible recompilar una aplicación en contexto después de agregar nuevos archivos de código fuente a él. La herramienta sólo compila los archivos nuevos o que se hayan modificado a menos que se incluya la opción -c. Nota: La compilación de una aplicación que contiene una aplicación anidada no compila la aplicación anidada. La aplicación anidada se debe compilar por separado. Compilar una aplicación para implementación Es posible compilar una aplicación para su implementación (compilación en una ubicación de destino) especificando el parámetro targetDir. targetDir puede constituir la ubicación final de la aplicación Web o la aplicación compilada se puede implementar de forma más completa. La utilización de la opción -u compila la aplicación de tal forma que se pueden realizar cambios en determinados archivos de la aplicación compilada sin necesidad de recompilarla. Aspnet_compiler.exe realiza una distinción entre tipos de archivos estáticos y dinámicos y los controla de manera diferente al crear la aplicación resultante. Los tipos de archivos estáticos son aquellos que no tienen un compilador asociado o que generan un proveedor, tales como archivos cuya denominación contiene extensiones .css, .gif, .htm, .html, .jpg o .js, entre otros. Estos archivos simplemente se copian en la ubicación de destino, con sus lugares relativos en la estructura de directorios que se ha conservado. Los tipos de archivos dinámicos son aquellos que tienen un compilador asociado o que generan un proveedor, incluyendo archivos con extensiones de nombre de archivo específicas de ASP.NET tales como .asax, .ascx, .ashx, .aspx, .browser y .master, entre otros. La herramienta de compilación de ASP.NET genera ensamblados a partir de estos archivos. Si se omite la opción -u, la herramienta también crea archivos con la extensión de nombre de archivo .COMPILED que asigna los archivos de código fuente a sus ensamblados. Para asegurar que se vaya a conservar la estructura de directorios del origen de la aplicación, la herramienta genera archivos de marcador en las correspondientes ubicaciones de la aplicación de destino. Se debe utilizar la opción -u para indicar que se puede modificar el contenido de la aplicación compilada. De lo contrario, se omiten las modificaciones subsiguientes o producen errores en tiempo de ejecución. Nombres de ensamblado fijos Algunos escenarios, como la implementación de una aplicación Web utilizando MSI Windows Installer, requieren la utilización de nombres de archivos coherentes y de contenido, así como estructuras de directorios igualmente coherentes para identificar ensamblados y valores de configuración para actualizaciones. En algunos casos, se puede utilizar la opción -fixednames para especificar que la herramienta de compilación de ASP.NET deberían compilar un ensamblado para cada archivo de código fuente en 33 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 lugar de utilizar los lugares donde varias páginas se compilan en ensamblados. Esto puede conducir a un gran número de ensamblados, por lo que si existe algún tipo de relación con escalabilidad debería utilizarse esta opción con precaución. Compilación de nombre seguro Las opciones -aptca, -delaysign, -keycontainer y -keyfile se proporcionan para que el usuario pueda utilizar Aspnet_compiler.exe para crear ensamblados de nombre seguro sin utilizar Herramienta de nombre seguro (Sn.exe) por separado. Estas opciones corresponden, respectivamente, a AllowPartiallyTrustedCallersAttribute, AssemblyDelaySignAttribute, AssemblyKeyNameAttribute y AssemblyKeyFileAttribute. Debido a que cada opción aplica el correspondiente atributo al ensamblado compilado y debido a que los atributos aparecen marcados con un AttributeUsageAttribute cuya propiedad AllowMultiple está establecida en false, la utilización de estas claves en el código fuente que ya ha sido marcado hace que se produzca un error de compilación. Clases de ASP.NET asociadas Varias clases en el espacio de nombres System.Web.Compilation hacen posible que su código pueda obtener acceso o invocar a Aspnet_compiler.exe fuera del entorno de IIS. La clase ClientBuildManager proporciona el método PrecompileApplication para compilar una aplicación. La clase ClientBuildManager también funciona con la clase ClientBuildManagerParameter, que permite especificar PrecompilationFlags el cual corresponde a las opciones utilizadas por esta herramienta y, de igual forma, para especificar claves de nombre seguro. Ejemplos El siguiente comando compila la aplicación WebApplication1 en contexto: Aspnet_compiler -v /WebApplication1 El siguiente comando compila la aplicación WebApplication1 en contexto. La aplicación compilada también incluye información de depuración y, a su vez, la herramienta agrega información de seguimiento de la pila si se debe crear un informe los errores. Aspnet_compiler -v /WebApplication1 -d -errorstack El siguiente comando compila la aplicación WebApplication1 para su implementación, utilizando la ruta de acceso física del directorio. También agrega dos atributos a los ensamblados de salida. Utiliza la opción -keyfile para agregarla a un atributo AssemblyKeyFileAttribute que especifica que el archivo Key.sn contiene información sobre el par de claves pública y privada que la herramienta debería utilizar para aplicar un nombre seguro al ensamblado generado. El comando también utiliza la opción -aptca para agregar un atributo AllowPartiallyTrustedCallersAttribute a los ensamblados generados. La aplicación Web compilada se crea en el directorio c:\applicationTarget. Aspnet_compiler -v /WebApplication1 -p c:\Documents and Settings\Default\My Documents\MyWebApplications\WebApplication1 keyfile c:\Documents and Settings\Default\My Documents\Key.sn -aptca c:\applicationTarget El comando siguiente compila el servicio WebService2 en la ruta de acceso de la metabase predeterminada, sobrescribiendo el directorio de destino SampleWebService con la aplicación compilada. Aspnet_compiler -m LM/W3SVC/1/ROOT/WebService2 -f c:\InetPub\wwwroot\SampleWebService HERRAMIENTA COMBINACIÓN DE ASP.NET (Aspnet_merge.exe) La herramienta Combinación de ASP.NET (Aspnet_merge.exe) permite combinar y administrar ensamblados creados por la herramienta Compilación de ASP.NET (Aspnet_compiler.exe). La herramienta Combinación de ASP.NET funciona en los ensamblados creados con ASP.NET versión 2.0 o posteriores. Existen dos versiones de la herramienta de combinación de ASP.NET: El que se proporciona con .NET Framework 2.0. Se puede utilizar esta versión para sitios web diseñados para .NET Framework 2.0, .NET Framework 3.0 o .NET Framework 3.5. El que se proporciona con .NET Framework 4. Puede utilizar esta versión de los sitios web diseñados para .NET Framework 2.0 y versiones posteriores, incluido .NET Framework 4. Cuando esta versión se utiliza para los sitios web diseñados para 34 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 .NET Framework 2.0, .NET Framework 3.0 o .NET Framework 3.5, proporciona un informe de errores mejorado comparado con la versión de .NET Framework 2.0 . La herramienta Compilación de ASP.NET se utiliza para precompilar una aplicación para su implementación. La herramienta crea un ensamblado para cada carpeta de contenido del sitio web de destino o crea un ensamblado para cada archivo de contenido. La herramienta Combinación de ASP.NET aporta flexibilidad para la implementación y administración de lanzamientos. Permite hacer lo siguiente: Crear un ensamblado para todo el sitio web. Crear un ensamblado para cada carpeta del sitio web y agregar un prefijo al nombre de ensamblado. Crear un único ensamblado sólo para los elementos de la interfaz de usuario del sitio web, como páginas y controles. La sintaxis del commando es la siguiente: aspnet_merge [-?] applicationPath [-keyfile filename [-delaysign]] [-o assemblyname | -w assemblyname | -prefix prefix] [-copyattrs [assemblyfile]] [-debug] [-nologo] [-errorstack] [-r] [-xmldocs] [-a] [-logfile logfile] [-allowattrs textfile] ARGUMENTOS Argumento Descripción applicationPath (Necesario) Especifica el nombre de la carpeta que contiene la aplicación para crear los ensamblados. Ésta es la operación de combinación predeterminada. Crea un número menor de ensamblados que la opción fixednames del compilador. OPCIONES Option Description -keyfile filename Especifica que se debe aplicar el atributo AssemblyKeyFileAttribute al ensamblado compilado. El atributo especifica el nombre del archivo que contiene el par de claves pública y privada utilizadas para generar un nombre seguro. Si se firman los ensamblados de entrada y la herramienta Combinación no 35 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 firma los ensamblados, recibirá un mensaje que advierte que se han quitado las claves. Si no se especifica un nombre de archivo de claves y un ensamblado tiene una clave pública y otro ensamblado no, se producirá un error en la herramienta Combinación . -delaysign Especifica que se debe aplicar el atributo AssemblyDelaySignAttribute al ensamblado generado. Este atributo especifica que un ensamblado sólo se debería firmar con el token de clave pública en lugar del par de claves pública/privada. Esta opción debe combinarse con la opción -keyfile. Si el atributo ya se aplica al ensamblado en los archivos de código, la herramienta Combinación produce una excepción. Cuando se utiliza la opción delaysign, si la comprobación del nombre seguro no está habilitada, el código generado por la herramienta Combinación se puede ejecutar antes de que se firme el código. Si no está habilitada la comprobación del nombre seguro, asegúrese de que el código no sea vulnerable a los ataques de usuarios malintencionados antes de que se complete la firma. -o assemblyname Especifica el nombre de un único ensamblado combinado para todo el contenido de la interfaz de usuario web y los ensamblados de nivel superior. Todos los archivos que tienen la extensión .compiled se modifican para que hagan referencia al ensamblado único. (Los archivos con la extensión .compiled se compilan a partir de contenido como .aspx, .master y .ascx.) Esta opción no se puede combinar con las opciones w o prefix. El parámetro assemblyname es necesario. -w assemblyname Especifica el nombre de un único ensamblado combinado para todo el contenido de la interfaz de usuario web (páginas y controles de usuario). Todos los archivos .aspx, .master y .ascx compilados se modifican para que hagan referencia al ensamblado único. Esto permite actualizar los elementos de la interfaz de usuario independientemente de la actualización del código. Los ensamblados de nivel superior para los recursos locales y globales no se combinan. Esta opción no se puede combinar con las opciones o o prefix. El parámetro assemblyname es necesario. -prefix prefix Especifica un prefijo para los nombres de ensamblados. El ensamblado de carpeta raíz sólo tiene el parámetro prefix como nombre del ensamblado. Los ensamblados de subcarpeta tienen el parámetro prefix combinado con el nombre de la subcarpeta. Por ejemplo, si una subcarpeta se denomina Admin, el ensamblado resultante se denominaría prefix.Admin .dll. Para los sitios web que no pueden ser actualizados, la herramienta Compilación compila los temas y recursos locales en ensamblados independientes en la carpeta Bin. Para los sitios web que se pueden actualizar, los temas y los recursos locales no se compilan en ensamblados en la carpeta Bin. En su lugar, se dejan en sus carpetas originales en la aplicación. Además, para los sitios actualizables, la herramienta Combinación modifica los archivos .aspx, .master y .ascx para que señalen al nuevo ensamblado combinado para la carpeta en la que residen los archivos. Esta opción no se puede combinar con las opciones o o w. El parámetro prefix es necesario. - Especifica que los ensamblados combinados debe tener asignados los mismos atributos de ensamblado copyattrs assemblyfile que el ensamblado especificado. Si no se especifica assemblyFile, se utiliza el ensamblado App_Code, aunque el ensamblado de nivel superior App_Code.dll no esté incluido en el resultado combinado. Si hay una incoherencia de atributos entre un ensamblado que se va a combinar y el ensamblado assemblyFile, se produce un error. Utilice la opción a para omitir la comprobación de atributos incoherentes o utilice la 36 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 opción allowattrs para especificar el atributo que se excluirá de la comprobación. Para los atributos que no están incluidos en la comprobación de coherencia, vea la descripción de la opción allowattrs en la tabla. -debug Especifica que el resultado de la depuración debe conservarse en el ensamblado combinado. -nologo Suprime el mensaje de copyright. -errorstack Especifica que la herramienta debería incluir información del seguimiento de la pila si se produce un error a la hora de compilar la aplicación. -r Quita los archivos .compiled del ensamblado de código principal (código de la carpeta App_Code). No utilice esta opción si su aplicación contiene una referencia de tipo explícito al ensamblado de código principal. -xmldocs Combina los archivos de documentación XML asociados a los ensamblados de entrada. La carpeta Bin del sitio combinado incluye un archivo XML. -a Obliga a la herramienta Combinación a combinar los ensamblados que no tienen aplicados todos los atributos AllowPartiallyTrustedCallersAttribute o que presentan incoherencias de atributos. AllowPartiallyTrustedCallersAttribute permite que los llamadores de confianza parcial tengan acceso a un ensamblado y se especifica durante la compilación realizada por la herramienta Compilación. Importante Cuando se utiliza la opción a, los ensamblados combinados que no se marcaron previamente para permitir llamadores de confianza parcial, se marcan con AllowPartiallyTrustedCallersAttribute. El resultado es que un código de confianza parcial puede llamar al ensamblado. -log logfile Escribe mensajes en el archivo especificado. -allowattrs textfile Especifica un archivo que contiene los atributos que se excluirán cuando la herramienta compruebe la coherencia de los atributos en ensamblados combinados. Cada línea del archivo puede ser el nombre completo de un atributo o un espacio de nombres completo. Si se especifica un espacio de nombres, se excluirán todos los atributos encontrados en ese espacio de nombres. Cada atributo o espacio de nombres debe estar en una línea diferente. Algunos atributos no tienen que especificarse explícitamente. La herramienta Combinación genera una advertencia si encuentra los siguientes atributos y, a continuación, sigue procesando. -? System.CodeDom.Compiler..::..GeneratedCodeAttribute System.Runtime.CompilerServices..::..CompilationRelaxationsAttribute System.Runtime.CompilerServices..::..RuntimeCompatibilityAttribute System.Diagnostics..::..DebuggableAttribute Microsoft.JScript..::..ReferenceAttribute Muestra la sintaxis de comandos y opciones para la herramienta. 37 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 La herramienta Combinación de ASP.NET proporciona una flexibilidad mayor al precompilar el sitio web que la que se logra sólo con la herramienta Compilación de ASP.NET. La herramienta Combinación de ASP.NET combina el resultado de la herramienta Compilación de ASP.NET para generar los ensamblados. Estos ensamblados combinados pueden mejorar administración de lanzamientos y la implementación de sitios web grandes. La herramienta Combinación de ASP.NET se puede utilizar de tres maneras: Combinar todos los resultados en un único ensamblado. Combinar el contenido de la interfaz de usuario web (páginas Web, máscaras, etc.) de cada carpeta en su propio ensamblado. Combinar todo el contenido de la interfaz de usuario web del sitio en un único ensamblado. Grupos de ensamblados La herramienta Compilación crea ensamblados de manera diferente en función del tipo del archivo de código fuente y de carpeta. El resultado de la herramienta Compilación puede clasificarse en dos grupos de ensamblados. La herramienta Combinación combina los dos grupos de ensamblados de manera diferente. Los dos grupos de ensamblados son los siguientes: Ensamblados de contenido de interfaz de usuario web, que se generan a partir de archivos de contenido de interfaz de usuario web como .aspx, .ascx, .master, .ashx, .skin y archivos .resx locales (en la carpeta App_LocalResources). La manera en que se combinan estos ensamblados depende de si el sitio precompilado es actualizable, lo que se determina mediante la opción u de la herramienta Compilación. Si un sitio compilado es actualizable, el contenido de la interfaz de usuario puede actualizarse sin volver a compilar el sitio. Cuando un sitio web es actualizable, los archivos de contenido permanecen en sus carpetas originales y sólo se combinan los archivos de código asociados. Si el sitio no es actualizable, los archivos de contenido .ascx, .master y .skin se quitan de su carpeta original. Los archivos .aspx de ASP.NET se reemplazan con un archivo de marcador que no tiene ningún contenido. En este caso, se combinan el contenido de la interfaz de usuario y el código. Ensamblados de nivel superior, que son ensamblados generados a partir de carpetas de aplicación como App_Code, App_GlobalResources, App_WebReferences. Los ensamblados de nivel superior también se generan para archivos especiales como Global.asax. Los ensamblados de nivel superior siempre se compilan en la carpeta Bin del sitio de implementación. El sitio de implementación final no tendrá una carpeta App_Code, App_GlobalResources o App_WebReferences ni un archivo Global.asax. En su lugar, el sitio de implementación final tendrá uno o varios ensamblados en el directorio Bin, en función de las opciones utilizadas con la herramienta Combinación. También se compilan siempre las carpetas definidas por el usuario, sólo que el sitio de implementación final mantiene la carpeta definida por el usuario cuando en ella hay archivos de contenido de interfaz de usuario. El contenido estático, como los archivos que tienen las extensiones .css, .gif, .htm, .html, .jpg, .js, quedan en sus ubicaciones en la estructura de directorios precompilada. La herramienta Combinación no los mueve ni los modifica. Escenarios de compilación y combinación Con ASP.NET 2.0, puede utilizar una combinación de compilación dinámica, precompilación con la herramienta Compilación, y combinación con la herramienta Combinación para adecuarse a sus objetivos de implementación y administración de lanzamientos. En la tabla siguiente se enumeran los diferentes escenarios de compilación y combinación, e indica cuándo se debería utilizar la herramienta Combinación. Escenario Notas Compilación dinámica (sin precompilación) La compilación dinámica es útil en escenarios de desarrollo rápidos. Visual Studio utiliza la compilación dinámica (cuando presiona F5 o CTRL+F5, solo se compilan dinámicamente la página en la que está trabajando y sus dependencias). Esto evita una compilación del sitio web completo. Precompile para crear un único ensamblado Cuando se precompila con la opción fixednames, puede realizar actualizaciones para cada archivo de contenido de interfaz incrementales de unidades tan pequeñas como páginas individuales, e implementar de usuario web utilizando de nuevo sólo las páginas cambiadas. Puede crear sitios precompilados actualizables y Aspnet_compiler.exe con la opción no actualizables mediante la opción u con la opción fixednames. La opción 38 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 fixednames. fixednames no afecta a la manera en que se combinan los ensamblados posteriormente mediante la herramienta Combinación. Para un sitio grande, el gran número de ensamblados creado por la opción fixednames puede producir problemas de administración de lanzamientos o implementación. Combine para crear un ensamblado para En este escenario, puede controlar los ensamblados en el nivel de carpeta de cada carpeta de contenido de interfaz de contenido de interfaz de usuario. Este escenario es como omitir la opción fixenames usuario web utilizando Aspnet_merge.exe cuando se utiliza la herramienta Compilación. La diferencia es que la herramienta con la opción prefix. Combinación permite más control sobre los nombres de los ensamblados finales derivados de la carpeta raíz y de las carpetas de contenido definidas por el usuario. Los ensamblados de nivel superior y el contenido estático no resultan afectados. Una posible desventaja de este escenario es que si cambia un archivo de una carpeta, debe implementar de nuevo el ensamblado de la carpeta y la página modificada. Puede combinar sitios precompilados actualizables y no actualizables mediante la opción prefix. Este escenario es el predeterminado si ejecuta la herramienta Combinación sin opciones. Combine para crear un único ensamblado En este escenario, todo el contenido de la interfaz de usuario se combina en un para todos los archivos de contenido de ensamblado que tiene el nombre especificado en el parámetro assemblyname. Esto interfaz de usuario web utilizando reduce el número total de ensamblados en el sitio final implementado. Sin embargo, Aspnet_merge.exe con la opción w. también requiere que implementa de nuevo el ensamblado de contenido de interfaz de usuario en caso de que cambie un archivo de contenido. Los ensamblados de nivel superior y el contenido estático no resultan afectados. Combine para crear un único ensamblado En este escenario, el sitio final implementado contiene sólo un ensamblado que tiene para todo el sitio web utilizando el nombre especificado en el parámetro assemblyname. Un ensamblado único Aspnet_merge.exe con la opción o. simplifica la implementación del sitio. Sin embargo, significa que si cambia cualquier contenido del sitio, debe volver a crear e implementar el ensamblado del sitio. Los ensamblados de nivel superior (App_Code, App_GlobalResources y App_WebReferences) resultan afectados porque están incluidos en el ensamblado único. El contenido estático no resulta afectado. Combinar una aplicación para su implementación Para combinar los ensamblados de un sitio web, se ejecuta la herramienta Combinación y se especifica la ubicación del sitio precompilado con el parámetro applicationPath. La herramienta Combinación de ASP.NET combina un sitio precompilado en contexto. En otras palabras, no crea una nueva copia combinada del sitio precompilado. El parámetro applicationPath puede ser la ubicación final de la aplicación web. Asimismo, se puede volver a implementar la aplicación de compilación, por ejemplo, copiando el directorio. Cuando la herramienta Combinación combina un sitio precompilado, conserva la ubicación de los archivos dinámicos cuando aparecen en el paso precompilado. El único cambio que la herramienta Combinación realiza al contenido de los archivos dinámicos es cambiar las directivas @ Page, @ Control y @ Master. Garantiza que los archivos que tienen estas directivas heredan del ensamblado combinado correcto en la carpeta Bin. Para los ensamblados que derivan de las carpetas definidas por el usuario (incluida la carpeta del sitio raíz), algunas opciones de combinación pueden crear nombres que difieren de los que aparecen en el sitio precompilado. Por ejemplo, la tabla siguiente muestra los nombres del ensamblado combinado cuando no se utiliza ninguna opción con la herramienta Combinación. El nombre de ensamblado para cada carpeta definida por el usuario es App_Web_nnnn.dll, 39 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 donde nnnn es un valor hash generado de forma interna. Carpeta del sitio precompilado Nombre del ensamblado combinado sin utilizar ninguna opción de Aspnet_merge.exe \ Root.dll Admin Admin.dll La tabla siguiente muestra los nombres del ensamblado combinado cuando se utiliza la opción prefix y el parámetro NewName. Carpeta del sitio precompilado Nombre del ensamblado combinado utilizando la opción prefix de Aspnet_merge.exe \ Nuevo nombre.dll Admin Nuevo nombre.Admin.dll Los temas se tratan de manera diferente en un sitio combinado que no es actualizable. En el sitio precompilado no combinado, hay un ensamblado independiente para cada tema. Cada ensamblado recibe el nombre App_Theme_Nombre del tema.dll. En el sitio combinado, hay un ensamblado denominado Theme.dll. Si el sitio precompilado es actualizable, no hay ningún ensamblado basado en temas en la carpeta Bin combinada. Solucionar problemas del proceso de combinación Mientras se está compilando o combinando un sitio web, la ruta de acceso de un ensamblado podría resultar mayor que la longitud máxima permitida para una ruta de acceso de archivo de Microsoft Windows. En ese caso, cuando se solicita un recurso del ensamblado combinado, se produce un error HttpException que indica que el recurso no se precompiló y no se puede solicitar. La longitud de la ruta de acceso de archivo máxima en Microsoft Windows es 260 caracteres. Si la ruta de acceso de un ensamblado supera este límite, debe acortar la ruta de acceso del sitio web o de sus subcarpetas. También podría tener que deshabilitar las copias sombra del archivo Web.config mediante la propiedad ShadowCopyBinAssemblies del elemento hostingEnvironment. Cuando se utiliza la herramienta Combinación con la opción o para crear un único ensamblado para el sitio, se producirá un error si el proceso de combinación crea referencias circulares. Hay dos soluciones posibles para esta situación: Utilizar en su lugar la opción w para que el archivo de código fuente que contiene la referencia circular se mantenga como referencia externa y no se combine. Separar los controles implicados en una referencia circular en directorios diferentes. Cuando se combinan ensamblados que tienen atributos incoherentes, utilice las instrucciones siguientes para asegurarse de que la operación de combinación sea correcta: Hacer una lista de los atributos incoherentes mediante la opción allowattrs. Utilizar las opciones copyattrs y asegurarse de que coinciden los atributos de todos los ensamblados que se van a combinar. Utilizar la opción a. Firmar ensamblados Las opciones keyfile y delaysign permiten utilizar la herramienta Combinación para crear ensamblados con nombre seguro sin utilizar la herramienta Nombre seguro (Sn.exe). Las opciones delaysign corresponden al atributo AssemblyDelaySignAttribute y la opción keyfile corresponde al atributo AssemblyKeyFileAttribute. Cada opción aplica el atributo correspondiente al ensamblado combinado. El atributo que se va a aplicar se marca con un atributo AttributeUsageAttribute cuya propiedad AllowMultiple es false. Por consiguiente, si utiliza estas opciones al combinar ensamblados que ya están marcados con uno de los atributos, no se realizará la combinación. 40 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Ejemplos El comando siguiente combina los ensamblados del sitio precompilado en el directorio C:\PrecompiledSite. Aspnet_merge C:\PrecompiledSite El comando siguiente combina los ensamblados de un sitio precompilado en el directorio C:\PrecompiledSite y firma los ensamblados combinados mediante el archivo KeyFile.snk. El sitio combinado tendrá un ensamblado para cada carpeta del sitio precompilado. Aspnet_merge C:\PrecompiledSite -keyfile KeyFile.snk El comando siguiente combina todos los ensamblados del sitio precompilado en el directorio C:\PrecompiledSite en un único ensamblado y asigna el nombre MyApp.dll al ensamblado resultante. El sitio combinado tendrá un ensamblado para todo el contenido de interfaz de usuario del sitio web. Aspnet_merge C:\PrecompiledSite -w MyApp.dll El comando siguiente combina todos los ensamblados del sitio precompilado en el directorio C:\PrecompiledSite en un único ensamblado y asigna el nombre MyApp.dll al ensamblado resultante. Aspnet_merge C:\PrecompiledSite -o MyApp.dll REALIZAR LA COMPILACIÓN CON EL COMPILADOR Just-In-Time (JIT) La compilación JIT convierte MSIL en código nativo a petición en el tiempo de ejecución de la aplicación, cuando el contenido de un ensamblado se carga y ejecuta. Common Language Runtime proporciona un compilador JIT para cada arquitectura de CPU compatible, por lo que los programadores pueden crear un conjunto de ensamblados MSIL que se puede compilar con un compilador JIT y se puede ejecutar en equipos distintos con diferentes arquitecturas. No obstante, el código administrado sólo se ejecutará en un determinado sistema operativo si llama a las API nativas específicas de la plataforma o a una biblioteca de clases específica de la plataforma. La compilación JIT tiene en cuenta el hecho de que durante la ejecución nunca se llamará a parte del código. En vez de utilizar tiempo y memoria para convertir todo el MSIL de un archivo ejecutable portable (PE) a código nativo, convierte el MSIL necesario durante la ejecución y almacena el código nativo resultante en memoria para que sea accesible en las llamadas posteriores que se produzcan en el contexto de ese proceso. El cargador crea y asocia un código auxiliar a cada método de un tipo cuando este tipo se carga y se inicializa. Cuando se llama a un método por primera vez, el código auxiliar pasa el control al compilador JIT, el cual convierte el MSIL del método en código nativo y modifica el código auxiliar para señalar directamente al código nativo generado. Por tanto, las siguientes llamadas al método compilado mediante un compilador JIT pasan directamente al código nativo. 8 IMPLEMENTAR CONTROLES ASOCIADOS CON DATOS: DATAGRID, DATALIST, REPEATER, LISTVIEW, GRIDVIEW, FORMVIEW, DETAILSVIEW, TREEVIEW, DATAPAGER Los controles de servidor Web enlazados a datos son controles que pueden ser enlazados a un control de origen de datos para facilitar la operación de mostrar y modificar datos en la aplicación Web. Los controles de servidor Web enlazados a datos son controles compuestos que combinan otros controles Web de ASP.NET, como los controles Label y TextBox, en un diseño único. Por ejemplo, un control enlazado a datos, como el control DetailsView se puede enlazar a un conjunto de resultados como una tabla de empleados que contenga el nombre de cada empleado, la dirección, el puesto de trabajo, etc. Dentro del control DetailsView, se pueden enlazar controles Label a valores de datos únicos, como el campo de nombre o de dirección para crear el diseño de datos de la página. 41 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Además de permitir enlazar el control a un conjunto de resultados de datos, los controles enlazados a datos permiten personalizar el diseño del control mediante la utilización de plantillas. También proporcionan un modelo cómodo para controlar y cancelar los eventos. Enlazar a datos un control de servidor Web enlazado a datos Se puede trabajar con un control enlazado a datos enlazándolo a un control de origen de datos como el control ObjectDataSource o el control SqlDataSource. El control de origen de datos conecta a un origen de datos como una base de datos o el objeto de nivel medio y, a continuación, recupera o actualiza los datos. El control enlazado a datos puede utilizar entonces este dato. Para realizar el enlace, se establece la propiedad DataSourceID del control enlazado a datos para señalar a un control de origen de datos. Cuando un control enlazado a datos se enlaza a un control de origen de datos, apenas se necesita escribir código adicional, o no se necesita en absoluto, para realizar operaciones con datos, porque el control enlazado a datos puede aprovecharse automáticamente de los servicios de datos proporcionados por el control de origen de datos. Nota: En las versiones 1.0 y 1.1 de ASP.NET, los controles enlazados a datos lo hacían utilizando la propiedad DataSource y era necesario escribir código para administrar operaciones como mostrar, paginar, ordenar, editar y eliminar datos. Aunque todavía se pueden enlazar controles a datos utilizando la propiedad DataSource (y el código existente), en ASP.NET versión 2.0 y posteriores se pueden realizar enlaces mediante la propiedad DataSourceID en su lugar. GridView Control El control GridView muestra los datos en forma de tabla y ofrece la función de ordenar columnas, paginar los datos y editar o eliminar un único registro. El control GridView es el sucesor del control DataGrid disponible en versiones anteriores de ASP.NET. Junto con la capacidad adicional para aprovechar las funciones de los controles de origen de datos, el control GridView ofrece mejoras como la capacidad de definir varios campos de clave principal, mejor personalización de la interfaz de usuario utilizando campos y plantillas enlazados y un nuevo modelo para controlar o cancelar eventos. DetailsView Control El control DetailsView representa un único registro cada vez en forma de tabla y proporciona la capacidad de paginar varios registros, así como de insertar, actualizar y eliminar registros. El control DetailsView se utiliza a menudo en escenarios maestrodetalle donde el registro seleccionado en un control maestro como el control GridView determina el registro que muestra el control DetailsView. FormView Control El control FormView representa un único registro cada vez desde un origen de datos y proporciona la capacidad de paginar varios registros, así como de insertar, actualizar y eliminar registros, de forma similar al control DetailsView. Sin embargo, la diferencia entre los controles FormView y DetailsView radica en que el control DetailsView utiliza un diseño tabular donde cada campo del registro se muestra como una fila del control. En cambio, el control FormView no especifica un diseño predefinido para mostrar un registro. Por tanto, debe crear plantillas que contengan controles para mostrar los campos individuales del registro. La plantilla contiene el formato, los controles y las expresiones de enlace que se utilizan para diseñar el formulario. Repeater Control El control Repeater representa una lista de sólo lectura de un conjunto de registros devueltos desde un origen de datos. Al igual que el control FormView, el control Repeater no especifica un diseño integrado. En su lugar, se crea el diseño para el control Repeater utilizando plantillas. DataList Control El control DataList representa datos en forma de tabla y permite mostrar registros de datos en diferentes diseños, por ejemplo ordenados en columnas o en filas. Puede configurar el control DataList para permitir a los usuarios editar o eliminar un registro de la tabla. (El control DataList no puede aprovechar las funciones de los controles de origen de datos para modificar datos; el usuario debe proporcionar este código). El control DataList se diferencia del control Repeater en que el control DataList coloca explícitamente los elementos en una tabla HTML, mientras que el Repeater no lo hace. 42 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 ListView Control El control ListView muestra los datos de un origen de datos en un formato que se define mediante plantillas. La plantilla contiene el formato, los controles y las expresiones de enlace que se utilizan para diseñar los datos. El control ListView resulta útil para los datos de cualquier estructura de repetición, de forma similar a los controles DataList y Repeater. Sin embargo, a diferencia de los controles DataList y Repeater, el control ListView admite implícitamente las operaciones de edición, inserción y eliminación, así como la funcionalidad de ordenación y paginación. 9 CARGAR LOS CONTROLES DEL USUARIO DINÁMICAMENTE La creación mediante programación de una instancia de un control de servidor en una página Web ASP.NET es muy similar a la creación de un control de usuario. Para crear una instancia de un control de usuario mediante programación, se siguen los siguientes pasos: 1. 2. 3. 4. 5. En el control de usuario, la directiva @ Control contiene un atributo ClassName que asigna una clase al control de usuario. En el ejemplo siguiente se establece el atributo ClassName para realizar el establecimiento inflexible de tipos en un control de usuario. <%@ Control className="MyUserControl" %> En la página donde se va a trabajar con el control de usuario, crear una referencia a dicho control con la directiva @ Reference. Cuando se cree el control de usuario mediante programación, el tipo inflexible para dicho control estará disponible para la página Web ASP.NET sólo después de haber creado una referencia al mismo. Por ejemplo, el código siguiente crea una referencia a un control de usuario creado en el archivo MyUserControl.ascx. <%@ Reference Control="MyUserControl.ascx" %> Nota: Utilizar la directiva @ Reference cuando se vaya a cargar el control mediante programación. Utilizar la directiva @ Register cuando se agregue un control de usuario a la página mediante declaración. Crear una variable de instancia para el control de usuario, utilizando el nombre de clase del control. La clase será parte del espacio de nombres ASP. Por ejemplo, si se desea crear una instancia del control de usuario declarada como clase Spinner, se debe utilizar sintaxis como la siguiente: Protected ASP.Spinner Spinner1; Crear una instancia del control de usuario en el código llamando al método LoadControl. Asignar los valores de las propiedades según sea necesario y, a continuación, agregar el control a la colección ControlCollection de un contenedor de la página, como un control PlaceHolder. Nota: Cuando se agregan controles al objeto ControlCollection mediante el método Add, dichos controles se colocan en la colección en el orden en el que se procesan. Si desea agregar un control en una posición específica de la colección, utilice el método AddAt y especifique la ubicación de índice en la que desea almacenar el control. Ejemplo En el ejemplo siguiente se muestra una página Web ASP.NET que carga un control de usuario mediante programación. La página incluye una directiva @ Reference para especificar el archivo del control. El método LoadControl lee el archivo y crea una instancia de éste en forma de control que se puede agregar a la página. <%@ Page Language="C#" %> <%@ Reference Control="~/Controls/Spinner.ascx" %> <script runat="server"> private ASP.Spinner Spinner1; protected void Page_Load(object sender, EventArgs e) { 43 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Spinner1 = (ASP.Spinner)LoadControl("~/Controls/Spinner.ascx"); // Set MaxValue first. Spinner1.MaxValue = 20; Spinner1.MinValue = 10; PlaceHolder1.Controls.Add(Spinner1); } protected void Button1_Click(object sender, EventArgs e) { Label1.Text = Spinner1.CurrentNumber.ToString(); } </script> <html> <head id="Head1" runat="server"> <title>Load User Control Programmatically</title> </head> <body> <form id="form1" runat="server"> <div> <asp:PlaceHolder runat=server ID="PlaceHolder1" /> <br /> <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /> <br /> <br /> <asp:Label ID="Label1" runat="server" Text=""></asp:Label> </div> </form> </body> 44 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 </html> 10 CREAR Y UTILIZAR CONTROLES PERSONALIZADOS: REGISTRO DE CONTROLES EN UNA PÁGINA, CREACIÓN DE CONTROLES EN PLANTILLA En ocasiones, es posible la necesidad de cierta funcionalidad en un control que no está incluida en los controles de servidor Web ASP.NET integrados. En estos casos, se pueden crear controles propios. Se dispone de dos opciones. Se pueden crear: Controles de usuario. Los controles de usuario son contenedores en los que puede colocar controles de formato y de servidor Web. A continuación puede tratar el control de usuario como una unidad y definir propiedades y métodos para el mismo. Controles personalizados. Un control personalizado es una clase escrita por un desarrollador que se deriva de Control o WebControl. Los controles de usuario son mucho más fáciles de crear que los controles personalizados, ya que es posible reutilizar los ya existentes. Esto permite crear con facilidad controles con elementos de interfaz de usuario complejos. Aunque las herramientas de diseño visual como Microsoft Visual Studio 2005 simplifican el desarrollo de controles, no son imprescindibles para la creación o generación de controles personalizados. Los controles pueden crearse con cualquier editor de texto y generarse desde la línea de comandos mediante los compiladores que forman parte de Kit de desarrollo de software de Windows (SDK). Independientemente del método empleado para crear el control, su aspecto y su comportamiento en tiempo de diseño en un diseñador visual serán los mismos. Los desarrolladores de páginas podrán agregar el control al cuadro de herramientas del diseñador visual, arrastrarlo a la superficie de diseño y tener acceso a sus propiedades y eventos en el explorador de propiedades. En algunos diseñadores visuales como Visual Studio 2005, los controles personalizados también admiten IntelliSense sin que sea necesario realizar ninguna operación adicional. Crear el control de servidor El control a crear, WelcomeLabel, es un control simple similar al control Label estándar. La clase WelcomeLabel se deriva de WebControl y define una propiedad Text que permite al desarrollador de páginas proporcionar una cadena de texto para dar la bienvenida a los usuarios de un sitio. WelcomeLabel agrega el nombre del usuario a la cadena de texto si dicho nombre está presente en el encabezado enviado por el explorador del usuario. Por ejemplo, si el desarrollador de páginas establece "Hola" como valor de la propiedad Text, WelcomeLabel representará "¡Hola, nombreDeUsuario!" u "¡Hola!" en función de si el nombre de usuario está presente en el encabezado. Para crear el código del control de servidor personalizado 1. Crear un archivo denominado WelcomeLabel.cs o WelcomeLabel.vb. 2. Agregar el código siguiente al archivo de código fuente del control: // WelcomeLabel.cs using System; using System.ComponentModel; using System.Security.Permissions; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace Samples.AspNet.CS.Controls { [ 45 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal), DefaultProperty("Text"), ToolboxData("<{0}:WelcomeLabel runat=\"server\"> </{0}:WelcomeLabel>") ] public class WelcomeLabel : WebControl { [ Bindable(true), Category("Appearance"), DefaultValue(""), Description("The welcome message text."), Localizable(true) ] public virtual string Text { get { string s = (string)ViewState["Text"]; return (s == null) ? String.Empty : s; } set { ViewState["Text"] = value; } } protected override void RenderContents(HtmlTextWriter writer) { 46 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 writer.WriteEncodedText(Text); if (Context != null) { string s = Context.User.Identity.Name; if (s != null && s != String.Empty) { string[] split = s.Split('\\'); int n = split.Length - 1; if (split[n] != String.Empty) { writer.Write(", "); writer.Write(split[n]); } } } writer.Write("!"); } } } Descripción del código Si el control representa un elemento de interfaz de usuario o cualquier otro elemento visible en el cliente, debe derivar el control de System.Web.UI.WebControls.WebControl (o una clase derivada). Si el control representa un elemento que no está visible en el explorador del cliente, como un elemento oculto o un elemento meta, se deriva el control de System.Web.UI.Control. La clase WebControl se deriva de Control y agrega propiedades relacionadas con el estilo como Font, ForeColor y BackColor. Por otra parte, los controles que se derivan de WebControl participan de las mismas características de temas de ASP.NET sin que sea necesario realizar ninguna operación adicional. Si un control extiende la funcionalidad de otro control existente, como Button, Label o Image, se puede derivar de ese control. Dado que WelcomeLabel extiende la funcionalidad del control Label, podría derivarse de Label. Sin embargo, se deriva WelcomeLabel de WebControl para mostrar cómo se debe definir una propiedad y los metadatos de las propiedades. WelcomeLabel define una propiedad, Text, y utiliza el estado de vista para almacenar el valor de dicha propiedad. Al utilizar el estado de vista se conserva el valor de Text en las distintas devoluciones de datos. En cada devolución de datos, se vuelve a crear la página y los valores se restauran desde el estado de vista. Si el valor de Text no se almacenara en el estado de vista, el valor se establecería en su valor predeterminado, Empty, en cada devolución de datos. La propiedad ViewState heredada de WebControl es un diccionario en el que se guardan los valores de datos. Los valores se escriben y se recuperan utilizando una clave String. En este caso, se utiliza "Text" como clave. Los elementos del diccionario son de tipo Object y deberá convertirlos al tipo de la propiedad. 47 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 El control WelcomeLabel representa su propiedad Text reemplazando el método RenderContents heredado. El parámetro pasado al método RenderContents es un objeto del tipo HtmlTextWriter, que es una clase de utilidad que tiene métodos para representar etiquetas y otros formatos HTML (así como de las variantes de HTML). WelcomeLabel realiza llamadas sucesivas al método Write del objeto HtmlTextWriter en lugar de realizar una concatenación de cadenas y, a continuación, invocar al método Write. Esto mejora el rendimiento debido a que el objeto HtmlTextWriter escribe directamente en la secuencia de salida. La concatenación de cadenas requiere tiempo y memoria para crear la cadena y, a continuación, escribe en la secuencia. Cuando se implementen la representación en los controles, se deberá seguir el modelo planteado. Nota: En general, cuando el control se deriva de WebControl y representa un solo elemento, se debe reemplazar el método RenderContents (no el método Render) para representar el contenido de las etiquetas del control. El método Render de WebControl invoca al método RenderContents después de representar la etiqueta de apertura del control y sus atributos de estilo. Si se reemplaza el método Render para escribir el contenido, el control perderá la lógica de representación de estilos integrada en el método Render de WebControl. Los atributos aplicados a WelcomeLabel contienen metadatos utilizados por Common Language Runtime y por las herramientas en tiempo de diseño. En el nivel de clase, WelcomeLabel se marca con los atributos siguientes: AspNetHostingPermissionAttribute es un atributo de seguridad de acceso a código. Hace que el compilador JIT compruebe que al código vinculado a WelcomeLabel se le ha concedido el permiso AspNetHostingPermission. Todas las clases de ASP.NET públicas se marcan con este atributo. Debe aplicar AspNetHostingPermissionAttribute a los controles como medida de seguridad frente a los llamadores de confianza parcial. DefaultPropertyAttribute es un atributo en tiempo de diseño que especifica la propiedad predeterminada de un control. En los diseñadores visuales, el explorador de propiedades generalmente resalta la propiedad predeterminada cuando el desarrollador de páginas hace clic en el control en la superficie de diseño. ToolboxDataAttribute especifica la cadena de formato del elemento. La cadena se convierte en el formato del control cuando se hace doble clic en el control en el cuadro de herramientas o cuando el control se arrastra del cuadro de herramientas a la superficie de diseño. En el caso de WelcomeLabel, la cadena crea este elemento: <aspSample:WelcomeLabel runat="server"> </aspSample:WelcomeLabel> El control WelcomeLabel también hereda dos atributos de la clase base WebControl: ParseChildrenAttribute y PersistChildrenAttribute. Se aplican como ParseChildren(true) y PersistChildren(false). Estos dos atributos funcionan juntos y con el atributo ToolboxDataAttribute a fin de que los elementos secundarios se interpreten como propiedades y las propiedades se conserven como atributos. Los atributos siguientes aplicados a la propiedad Text de WelcomeLabel son atributos estándar en tiempo de diseño que se aplican generalmente a todas las propiedades públicas de los controles: BindableAttribute, especificado como true o false, indica a los diseñadores visuales si tiene sentido enlazar la propiedad a datos. Por ejemplo, en Visual Studio 2005, si una propiedad se marca con Bindable(true), esta se mostrará en el cuadro de diálogo DataBindings. Si la propiedad no se marca con este atributo, el explorador de propiedades deduce que el valor es Bindable(false). CategoryAttribute, especifica en qué categoría se debe situar la propiedad en el explorador de propiedades del diseñador visual. Por ejemplo, Category("Appearance") indica al explorador de propiedades que muestre la propiedad en la categoría Apariencia cuando el desarrollador de páginas utilice la vista por categorías del explorador de propiedades. Se puede especificar un argumento de cadena correspondiente a una categoría existente en el explorador de propiedades o crear una categoría propia. DescriptionAttribute especifica una breve descripción de la propiedad. En Visual Studio 2005, el explorador de propiedades muestra la descripción de la propiedad seleccionada en la parte inferior de la ventana Propiedades. DefaultValueAttribute especifica un valor predeterminado para la propiedad. Este valor debe ser idéntico al valor predeterminado que se devuelve desde el descriptor de acceso de la propiedad (captador). En Visual Studio 2005, DefaultValueAttribute permite al desarrollador de páginas restablecer el valor de una propiedad a su valor predeterminado si se abre el menú de acceso directo en la ventana Propiedades y se hace clic en el botón Restablecer. LocalizableAttribute , especificado como true o false, indica a los diseñadores visuales si tiene sentido traducir la propiedad. Cuando una propiedad se marca con Localizable(true), el diseñador visual la incluye cuando se serializan los 48 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 recursos traducibles. El diseñador conservará el valor de la propiedad en el archivo de recursos de referencia cultural neutra u otro origen de localización cuando el control se sondee para buscar propiedades localizables. Nota: En las versiones 1.0 y 1.1 de ASP.NET, LocalizableAttribute no se podía aplicar a los controles de servidor personalizados ya que el modelo de localización de ASP.NET era distinto en dichas versiones. Los atributos en tiempo de diseño aplicados a un control y sus miembros no afectan al funcionamiento del control en tiempo de ejecución, pero mejoran la experiencia del desarrollador cuando el control se utiliza en un diseñador visual. Puede ver una lista completa de los atributos en tiempo de diseño, tiempo de análisis y tiempo de ejecución para los controles de servidor en Atributos de metadatos para controles de servidor personalizados. Utilizar el directorio App_Code para probar los controles sin compilación Se puede utilizar la característica de compilación dinámica de ASP.NET para probar el control en una página sin compilarlo en un ensamblado. ASP.NET compila dinámicamente el código colocado en el directorio App_Code bajo la raíz de un sitio Web ASP.NET. De este modo, es posible obtener acceso a las clases de los archivos de código fuente de este directorio desde las páginas sin necesidad de compilarlas manualmente en ensamblados. Si coloca los archivos de código fuente para los controles en el directorio App_Code, los cambios que realice en el código de los controles se reflejarán de forma inmediata en las páginas que utilizan dichos controles. Nota: El directorio App_Code es una nueva característica que no estaba disponible en ASP.NET 1.0 y 1.1. El uso del directorio App_Code para las pruebas iniciales del control es opcional. Los pasos principales para generar un control de servidor son los mismos que en las versiones anteriores. Para crear el sitio Web ASP.NET y el directorio App_Code 1. 2. 3. Crear un sitio Web denominado ServerControlsTest. Se puede crear el sitio en IIS como un directorio virtual denominado ServerControlsTest. Crear un directorio App_Code directamente bajo el directorio raíz del sitio Web (también denominado raíz de la aplicación Web). Copiar el archivo de código fuente del control (WelcomeLabel.cs o WelcomeLabel.vb) en el directorio App_Code. Crear un prefijo de etiqueta Un prefijo de etiqueta es el prefijo, como "asp" en <asp:Table />, que aparece antes del nombre de tipo del control cuando éste se crea mediante declaración en una página. Para habilitar el control a fin de que pueda utilizarse mediante declaración en una página, ASP.NET necesita que se asigne un prefijo de etiqueta al espacio de nombres del control. El desarrollador de páginas puede proporcionar una asignación de prefijo de etiqueta y espacio de nombres agregando una directiva @ Register en cada página que utiliza el control personalizado, como en el ejemplo siguiente: Copiar <%@ Register TagPrefix="aspSample" Namespace="Samples.AspNet.CS.Controls"%> La directiva @ Register de ASP.NET 2.0 es la misma que en ASP.NET 1.0 y ASP.NET 1.1. Se podrá observar que el atributo assembly que especifica el nombre de ensamblado del control no aparece en la directiva Register anterior. Cuando falta el atributo assembly, ASP.NET deduce que el ensamblado se ha compilado dinámicamente a partir de los archivos de código fuente del directorio App_Code. Como alternativa al uso de la directiva @ Register en cada página .aspx, el desarrollador de páginas puede especificar la asignación de prefijo de etiqueta y espacio de nombres en el archivo Web.config. Esto resulta útil si el control personalizado se utiliza en varias páginas de la aplicación Web. En el procedimiento siguiente se describe cómo especificar la asignación del prefijo de etiqueta en el archivo Web.config. Para agregar una asignación de prefijo de etiqueta al archivo Web.config 1. Crear un archivo de texto denominado Web.config bajo el directorio raíz del sitio Web si dicho archivo no existe todavía. 2. Colocar el siguiente código. <?xml version="1.0"?> <configuration> 49 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 <system.web> <pages> <controls> <add tagPrefix="aspSample" namespace="Samples.AspNet.CS.Controls"> </add> </controls> </pages> </system.web> </configuration> La sección resaltada muestra una entrada de prefijo de etiqueta que asigna el prefijo "aspSample" al espacio de nombres Samples.AspNet.CS.Controls. Nota: El prefijo de etiqueta debe ser un elemento secundario de la sección controls, que debe estar bajo la sección pages, que a su vez debe ser un elemento secundario de system.web. Tras haber especificado la asignación del prefijo de etiqueta en el archivo de configuración, puede utilizar el control WelcomeLabel mediante declaración (como <aspSample:WelcomeLabel />) en cualquier página del sitio Web. Crear una página para utilizar el control Para crear una página que utilice el control personalizado 1. Crear un archivo de texto denominado WelcomeLabelTest.aspx en el sitio Web. 2. Copiar el formato siguiente en el archivo WelcomeLabelTest.aspx. <%@ Page Language="C#"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <title>WelcomeLabel Test</title> </head> <body> <form id="form1" runat="server"> <div> 50 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 <aspSample:WelcomeLabel Text="Hello" ID="WelcomeLabel1" runat="server" BackColor="Wheat" ForeColor="SaddleBrown" /> </div> </form> </body> </html> 3. Visualizar el archivo WelcomeLabelTest.aspx en el explorador escribiendo la dirección URL siguiente en la barra de direcciones: http://localhost/ServerControlsTest/WelcomeLabelTest.aspx 4. Realizar algún cambio en el código fuente del control. Por ejemplo, escribir una cadena adicional agregando esta línea de código al final del método RenderContents: writer.Write("Testing how the App_Code directory works."); 5. Actualizar la página WelcomeLabelTest.aspx en el explorador. Se verá que los cambios realizados en el control se reflejan en la página aunque no se haya compilado el control. Además de la propiedad Text del control WelcomeLabel definido de forma explícita, la instancia del control de la página tiene las propiedades BackColor y ForeColor no definidas. El control WelcomeLabel obtiene estas y otras propiedades relacionadas con el estilo heredándolas de la clase base WebControl. Por otra parte, al control WelcomeLabel se le puede asignar una máscara y puede formar parte de un tema sin que sea necesario realizar ninguna operación adicional. Compilar el control en un ensamblado Aunque el directorio App_Code permite probar el control sin compilarlo, si se desea distribuir a otros desarrolladores como código de objeto, se debe compilar. Por otra parte, el control no se puede agregar al cuadro de herramientas del diseñador visual a menos que se compile en un ensamblado. Para compilar el control en un ensamblado 1. 2. Establecer la variable PATH del entorno de Windows del equipo para que incluya la ruta de acceso a la instalación de .NET Framework. Generalmente, .NET Framework está instalado en el directorio de instalación de Windows, en \Microsoft.NET\Framework\númeroDeVersión. Ejecutar el comando siguiente desde el directorio que ha creado para los archivos de código fuente. csc /t:library /out:Samples.AspNet.CS.Controls.dll /r:System.dll /r:System.Web.dll *.cs La opción del compilador /t:library indica al compilador que debe crear una biblioteca en lugar de un ensamblado ejecutable. La opción /out proporciona un nombre para el ensamblado y la opción /r muestra los ensamblados que están vinculados al ensamblado. Incrustar un icono en el ensamblado del control Generalmente, los diseñadores visuales como Visual Studio 2005 usan un icono predeterminado (como la imagen de un engranaje) para mostrar un control en el cuadro de herramientas. Como opción para el control, se puede personalizar su aspecto en el cuadro de herramientas incrustando un mapa de bits de 16 por 16 píxeles en el ensamblado del control. Por convención, los diseñadores visuales utilizan el píxel situado más abajo en la parte izquierda del mapa de bits como color transparente. Utilizar TagPrefixAttribute para proporcionar una asignación de prefijo de etiqueta y espacio de nombres 51 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Se puede especificar un prefijo de etiqueta en la página o en el archivo Web.config. Opcionalmente también se puede sugerir el prefijo de etiqueta predeterminado que el diseñador visual deba utilizar para el control, incluyendo el atributo System.Web.UI.TagPrefixAttribute del nivel de ensamblado. El atributo TagPrefixAttribute es útil porque proporciona un prefijo de etiqueta para que el diseñador visual pueda utilizarlo si no encuentra una asignación de prefijo de etiqueta en el archivo Web.config o en una directiva Register de la página. El prefijo de etiqueta se registra con la página la primera vez que se hace doble clic en el control en el cuadro de herramientas o cuando el control se arrastra del cuadro de herramientas a la página. Si se decide usar el atributo TagPrefixAttribute, se puede especificar en un archivo independiente que se compila con los controles. Por convención, el archivo se denomina AssemblyInfo.extensiónDeIdioma, como AssemblyInfo.cs o AssemblyInfo.vb. En el procedimiento siguiente se describe cómo especificar los metadatos de TagPrefixAttribute. Nota: Si no se especifica el atributo TagPrefixAttribute en el ensamblado del control y el desarrollador de páginas no especifica la asignación de prefijo de etiqueta y espacio de nombres en la página o en el archivo Web.config, el diseñador visual podría crear un prefijo de etiqueta predeterminado. Por ejemplo, Visual Studio 2005 creará su propia etiqueta (como cc1) para el control cuando éste se arrastre desde el cuadro de herramientas. Para agregar una asignación de espacio de nombres y prefijo de etiqueta mediante TagPrefixAttribute 1. Crear un archivo denominado AssemblyInfo.cs o AssemblyInfo.vb en el directorio del código fuente y agregar el código siguiente al archivo. using System; using System.Web.UI; [assembly: TagPrefix("Samples.AspNet.CS.Controls", "aspSample")] tributo de prefijo de etiqueta crea una asignación Samples.AspNet.VB.Controls y el prefijo aspSample. 2. entre el espacio de nombres Samples.AspNet.CS.Controls o Compilar todos los archivos de código fuente utilizando el comando de compilación. Utilizar el control personalizado compilado en una página ASP.NET Para probar la versión compilada del control personalizado es necesario que las páginas del sitio Web puedan tener acceso al ensamblado del control. Para hacer que el sitio Web tenga acceso al ensamblado del control 1. Crear un directorio Bin bajo la raíz del sitio Web. 2. Copiar el ensamblado del control (Samples.AspNet.CS.Controls.dll o Samples.AspNet.VB.Controls.dll) en el directorio Bin. 3. Eliminar el archivo de código fuente del control del directorio App_Code. Si no se elimina los archivos de código fuente, el tipo del control existirá tanto en el ensamblado compilado como en el ensamblado generado dinámicamente creado por ASP.NET. Esto creará una referencia ambigua al cargar el control y las páginas en las que se utilice dicho control producirán un error de compilador. El ensamblado creado en este ejemplo se denomina ensamblado privado porque debe estar colocado en un directorio Bin del sitio Web ASP.NET para permitir que las páginas del sitio utilicen el control. No es posible tener acceso al ensamblado desde otras aplicaciones a menos que también se instale una copia con dichas aplicaciones. Si se crea controles para aplicaciones de hospedaje Web compartidas, normalmente los empaquetará en un ensamblado privado. No obstante, si se crea controles para su uso en un entorno de hospedaje dedicado o crea un conjunto de controles que un ISP pone a disposición de todos sus clientes, se podría necesitar empaquetar los controles en un ensamblado compartido (con nombre seguro) que esté instalado en la Caché de ensamblados global. A continuación, se debe modificar la asignación del prefijo de etiqueta creada en Web.config para especificar el nombre de ensamblado del control. Para modificar la asignación del prefijo de etiqueta de Web.config 52 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Editar el archivo Web.config para agregar un atributo assembly al elemento addtagPrefix: <controls> <add tagPrefix="aspSample" namespace="Samples.AspNet.CS.Controls" assembly="Samples.AspNet.CS.Controls"> </add> </controls> El atributo assembly especifica el nombre del ensamblado en el que está el control. El elemento addtagPrefix asigna un prefijo de etiqueta a una combinación de espacio de nombres y ensamblado. Cuando ASP.NET genera dinámicamente el ensamblado a partir de los archivos de código fuente del directorio App_Code, el atributo assembly no es necesario. Cuando no se utiliza el atributo assembly, ASP.NET carga el tipo del control de los ensamblados generados dinámicamente desde el directorio App_Code. Para ver la página que utiliza el control personalizado Visualizar la página WelcomeLabelTest.aspx en el explorador escribiendo la dirección URL siguiente en la barra de direcciones: http://localhost/ServerControlsTest/WelcomeLabelTest.aspx Si se utiliza el control en un diseñador visual como Visual Studio 2005, podrá agregar el control al cuadro de herramientas, arrastrarlo del cuadro de herramientas a la superficie de diseño y tener acceso a sus propiedades y eventos en el explorador de propiedades. Además, en Visual Studio 2005, el control es totalmente compatible con IntelliSense en la vista de código fuente del diseñador de páginas y en el editor de código. Esto incluye la finalización de instrucciones en un bloque script así como la compatibilidad con el explorador de propiedades cuando el desarrollador de páginas hace clic en la etiqueta del control. CONTROL DE SERVIDOR CON PLANTILLA En este ejemplo se muestra un control denominado VacationHome que describe cómo implementar un control de servidor con plantilla. El control VacationHome define dos propiedades, Title y Caption. Mediante la edición del elemento Template en el control, el desarrollador de páginas especifica los controles y el formato que definen la interfaz de usuario del control. El control también permite al desarrollador de páginas utilizar la sintaxis <#% Container%>, a fin de que Title y Caption puedan mostrarse en la interfaz de usuario. El diseñador de páginas podría crear una página Web ASP.NET que presentara el aspecto siguiente: <aspSample:VacationHome ID="VacationHome1" Title="Condo for Rent in Hawaii" Caption="Ocean view starting from $200" Runat="server" Width="230px" Height="129px"> <Template> <table bgcolor="aqua" align="center" id="Table1" runat="server" style="width: 286px; height: 260px"> <tr> <td style="width: 404px" align="center"> 53 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 <asp:Label ID="Label1" Runat="server" Text="<%#Container.Title%>" Font-Names="Arial, Helvetica"></asp:Label> </td> </tr> <tr> <td style="width: 404px"> <asp:Image ID="Image1" Runat="server" ImageUrl="~/images/hawaii.jpg" /> </td> </tr> <tr> <td style="width: 404px; height: 26px;" align="center"> <asp:Label ID="Label2" Runat="server" Text="<%#Container.Caption%>" Font-Names="Arial, Helvetica"> </asp:Label> </td> </tr> </table> </Template> </aspSample:VacationHome> Lista de código del control VacationHome // VacationHome.cs using System; using System.ComponentModel; using System.Drawing; using System.Security.Permissions; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; 54 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 using System.Web.UI.Design; namespace Samples.AspNet.CS.Controls { [ AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal), Designer(typeof(VacationHomeDesigner)), DefaultProperty("Title"), ToolboxData( "<{0}:VacationHome runat=\"server\"> </{0}:VacationHome>"), ] public class VacationHome : CompositeControl { private ITemplate templateValue; private TemplateOwner ownerValue; [ Bindable(true), Category("Data"), DefaultValue(""), Description("Caption") ] public virtual string Caption { get { string s = (string)ViewState["Caption"]; return (s == null) ? String.Empty : s; 55 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 } set { ViewState["Caption"] = value; } } [ Browsable(false), DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden) ] public TemplateOwner Owner { get { return ownerValue; } } [ Browsable(false), PersistenceMode(PersistenceMode.InnerProperty), DefaultValue(typeof(ITemplate), ""), Description("Control template"), TemplateContainer(typeof(VacationHome)) ] public virtual ITemplate Template { get { 56 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 return templateValue; } set { templateValue = value; } } [ Bindable(true), Category("Data"), DefaultValue(""), Description("Title"), Localizable(true) ] public virtual string Title { get { string s = (string)ViewState["Title"]; return (s == null) ? String.Empty : s; } set { ViewState["Title"] = value; } } protected override void CreateChildControls() { Controls.Clear(); 57 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 ownerValue = new TemplateOwner(); ITemplate temp = templateValue; if (temp == null) { temp = new DefaultTemplate(); } temp.InstantiateIn(ownerValue); this.Controls.Add(ownerValue); } public override void DataBind() { CreateChildControls(); ChildControlsCreated = true; base.DataBind(); } } [ ToolboxItem(false) ] public class TemplateOwner : WebControl { } #region DefaultTemplate sealed class DefaultTemplate : ITemplate { 58 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 void ITemplate.InstantiateIn(Control owner) { Label title = new Label(); title.DataBinding += new EventHandler(title_DataBinding); LiteralControl linebreak = new LiteralControl("<br/>"); Label caption = new Label(); caption.DataBinding += new EventHandler(caption_DataBinding); owner.Controls.Add(title); owner.Controls.Add(linebreak); owner.Controls.Add(caption); } void caption_DataBinding(object sender, EventArgs e) { Label source = (Label)sender; VacationHome container = (VacationHome)(source.NamingContainer); source.Text = container.Caption; } void title_DataBinding(object sender, EventArgs e) { Label source = (Label)sender; VacationHome container = (VacationHome)(source.NamingContainer); source.Text = container.Title; 59 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 } } #endregion public class VacationHomeDesigner : ControlDesigner { public override void Initialize(IComponent Component) { base.Initialize(Component); SetViewFlags(ViewFlags.TemplateEditing, true); } public override string GetDesignTimeHtml() { return "<span>This is design-time HTML</span>"; } public override TemplateGroupCollection TemplateGroups { get { TemplateGroupCollection collection = new TemplateGroupCollection(); TemplateGroup group; TemplateDefinition template; VacationHome control; control = (VacationHome)Component; group = new TemplateGroup("Item"); template = new TemplateDefinition(this, "Template", control, "Template", true); group.AddTemplateDefinition(template); 60 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 collection.Add(group); return collection; } } } } Descripción del código Un control con plantilla extiende CompositeControl si se agrega una propiedad del tipo ITemplate y se define el contenedor de nombres para el control. La definición del contenedor de nombres permitirá al desarrollador de páginas utilizar la sintaxis <#%Container%> en la definición de la plantilla. El control con plantilla también define una propiedad de un tipo que se deriva de Control para alojar los controles definidos en la plantilla. También se implementan reemplazos de atributos y miembros concretos para coordinar la propiedad de la plantilla, el control de host y el comportamiento del contenedor de nombres. En la lista siguiente se resumen los requisitos de implementación principales para un control con plantilla como muestra VacationHome. En la explicación que acompaña a la lista se proporciona información detallada sobre cada uno de los requisitos. El control VacationHome muestra: La derivación de la clase base CompositeControl. Un control con plantilla es una clase especial de control compuesto. También se puede derivar de WebControl, pero CompositeControl agrega la implementación para INamingContainer, lo que permite el uso de la sintaxis <#%Container%>. La implementación de una propiedad del tipo ITemplate y la aplicación a la misma de atributos de metadatos relevantes para definir su persistencia y su contenedor de nombres. La exposición de una propiedad del tipo Control o una clase derivada de Control que sirve para alojar los controles definidos en el elemento de plantilla. Este control se denomina contenedor de plantilla. El reemplazo del método CreateChildControls para crear instancias de los controles con plantilla en la colección Controls del contenedor de plantilla. Opcionalmente, la definición de la plantilla predeterminada que el control utilizará cuando el desarrollador de páginas no especifique ninguna plantilla. Opcionalmente, la definición de una clase de diseñador para el control. La clase de diseñador permite al desarrollador de páginas editar las plantillas en un diseñador visual. Los atributos aplicados a la propiedad ITemplate son BrowsableAttribute, PersistenceModeAttribute y TemplateContainerAttribute. TemplateContainerAttribute especifica el tipo del control que el analizador de páginas debe utilizar durante la resolución de la variable Container en una expresión como <#%Container.Title%> de una plantilla. El tipo especificado debe implementar INamingContainer y definir las propiedades de datos (en este caso, Caption y Title) para el control. Este tipo puede ser el tipo del propietario de la plantilla o de un control situado más arriba en el árbol de control. En el control VacationHome, el control cuyo tipo se pasa al constructor TemplateContainerAttribute no es el propietario de la plantilla, sino el propio control VacationHome. BrowsableAttribute se establece en false, dado que generalmente las plantillas no se editan en la ventana de edición de propiedades del diseñador visual. PersistenceModeAttribute se establece en InnerProperty, dado que la especificación de la plantilla está escrita como un elemento interno del control. El control con plantilla debe definir una propiedad del tipo Control que se convierte en el contenedor para los controles creados por la plantilla. En el ejemplo, el control VacationHome define la propiedad Owner, que es del tipo TemplateOwner, que a su vez se deriva de WebControl. La clase TemplateOwner está marcada con ToolboxItem(false) para indicar que la clase TemplateOwner no necesita la compatibilidad del cuadro de herramientas en el diseñador visual. Se crean instancias de los controles de la plantilla y se agregan a la propiedad Controls del control Owner. Si el control expone varias propiedades ITemplate, podría definir una propiedad de contenedor de plantilla independiente para cada plantilla. La propiedad Owner se expone como propiedad pública. Esto permite al diseñador de páginas utilizar el método FindControl para hacer referencia a controles concretos en la plantilla en tiempo de ejecución. 61 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 El control VacationHome reemplaza al método base CreateChildControls. El método CreateChildControls crea instancias de los controles especificados en la propiedad Template y los agrega a la colección Controls del objeto Owner. A continuación, el objeto Owner se agrega a la colección Controls de la instancia de VacationHome, con lo que se podrá representar el control. Si el desarrollador de páginas no ha definido una plantilla, VacationHome creará una instancia de DefaultTemplate, que se deriva de ITemplate. El método InstantiateIn crea dos controles Label para mostrar las propiedades Title y Caption. Se crea un método controlador de eventos para el evento DataBinding de cada control. El controlador de eventos DataBinding establece la propiedad Text en la propiedad correspondiente (Title o Caption) de VacationHome. La clase VacationHomeDesigner que implementa un diseñador para la clase VacationHome se deriva de ControlDesigner. Durante la inicialización, el método SetViewFlags, al que se llama con TemplateEditing, permite la edición de la plantilla en tiempo de diseño. El método GetDesignTimeHtml se reemplaza para representar el control cuando no está en modo de edición de plantillas. El código de la propiedad TemplateGroups reemplazada define un grupo de plantillas que contiene una plantilla. Cada objeto TemplateGroup agrega una opción de edición de plantillas a la interfaz de usuario de edición de plantillas del diseñador visual. (En Visual Studio 2005, las opciones de edición de plantillas se muestran en una etiqueta inteligente asociada al control.) En el control VacationHome, la única opción de edición es "Item". Cada objeto TemplateDefinition crea una plantilla para la edición en el diseñador. El parámetro templatePropertyName del constructor TemplateDefinition especifica el nombre de la propiedad de plantilla en el control. DesignerAttribute se aplica a la clase VacationHome para especificar la clase de diseñador. Página de prueba del control VacationHome El ejemplo siguiente muestra una página .aspx que utiliza el control VacationHome. La primera instancia del control de la página especifica una plantilla para la propiedad ITemplate del control. La segunda instancia no especifica la propiedad ITemplate, lo que hace que el control VacationHome utilice su plantilla predeterminada en tiempo de ejecución. <%@ Page Language="C#"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { VacationHome1.DataBind(); VacationHome2.DataBind(); } } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <title> VacationHome Control Test Page 62 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 </title> </head> <body> <form id="form1" runat="server"> <aspSample:VacationHome ID="VacationHome1" Title="Condo for Rent in Hawaii" Caption="Ocean view starting $200" Runat="server" Width="230px" Height="129px"> <Template> <table id="TABLE1" runat="server" style="width: 286px; height: 260px; background-color:Aqua; text-align:center"> <tr> <td style="width: 404px" align="center"> <asp:Label ID="Label1" Runat="server" Text="<%#Container.Title%>" Font-Names="Arial, Helvetica"></asp:Label> </td> </tr> <tr> <td style="width: 404px"> <asp:Image ID="Image1" Runat="server" ImageUrl="~/images/hawaii.jpg" AlternateText="Hawaii home" /> </td> </tr> <tr> <td style="width: 404px; height: 26px;" align="center"> <asp:Label ID="Label2" Runat="server" Text="<%#Container.Caption%>" Font-Names="Arial, Helvetica"> 63 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 </asp:Label> </td> </tr> </table> </Template> </aspSample:VacationHome> <br /> <br /> <br /> The VacationHome control rendered with its default template: <br /> <br /> <aspSample:VacationHome ID="VacationHome2" Title="Condo for Rent in Hawaii" Caption="Ocean view starting $200" Runat="server" BorderStyle="Solid" BackColor="#66ffff" Height="30px" Width="238px" Font-Names="Arial, Helvetica" /> </form> </body> </html> 11 IMPLEMENTAR LA VALIDACIÓN EN EL CLIENTE Y EN EL SERVIDOR: REQUIREDFIELDVALIDATOR, COMPAREVALIDATOR, REGULAREXPRESSIONVALIDATOR, CUSTOMVALIDATOR, RANGEVALIDATOR Un aspecto importante de la creación de páginas Web ASP.NET para la entrada de datos por el usuario consisten en poder comprobar que la información que introducen los usuarios es válida. ASP.NET ofrece un conjunto de controles de validación que proporciona una forma eficaz y fácil de usar para comprobar errores y, si es necesario, mostrar mensajes al usuario VALIDAR LA INFORMACIÓN ESPECIFICADA POR EL USUARIO EN PÁGINAS WEB ASP.NET Mediante los controles de validación se puede agregar validación de entrada a las páginas Web ASP.NET. Los controles de validación proporcionan un mecanismo fácil de utilizar para todos los tipos comunes de validación estándar (por ejemplo, probar fechas válidas o valores comprendidos en un intervalo), además de otras formas para proporcionar validación escrita personalizada. Además, los controles de validación permiten personalizar completamente cómo se muestra la información de errores al usuario. Los controles de validación se pueden utilizar con cualquier control que se coloque en una página Web ASP.NET, incluidos los controles HTML y de servidor Web. Nota de seguridad: De forma predeterminada, las páginas Web ASP.NET comprueban automáticamente la entrada de datos potencialmente malintencionados. 64 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Utilizar controles de validación Habilitar la validación de los datos introducidos por el usuario agregando controles de validación a la página como se haría con otros controles de servidor. Existen controles para distintos tipos de validación, como la comprobación de un intervalo o la comparación de modelos. Cada control de validación hace referencia a un control de entrada (un control de servidor) situado en otra parte de la página. Cuando se procesan los datos introducidos por el usuario (por ejemplo, cuando se envía una página), el control de validación comprueba dichos datos y establece una propiedad para indicar si han pasado la comprobación. Una vez que se ha llamado a todos los controles de validación, se establece una propiedad en la página que indica si alguna de las comprobaciones de validación ha producido un error. Los controles de validación se pueden asociar en grupos de validación a fin de que los controles que pertenezcan a un grupo común se validen juntos. Se puede utilizar estos grupos para habilitar o deshabilitar de forma selectiva la validación para controles relacionados en una página. Otras operaciones de validación, como mostrar un control ValidationSummary o llamar al método GetValidators, pueden hacer referencia al grupo de validación. En el código se puede probar el estado de la página y de los controles individuales. Por ejemplo, se podría probar el estado de los controles de validación antes de actualizar un registro de datos con información introducida por el usuario. Si se detecta un estado no válido, se omite la actualización. Normalmente, si una comprobación de validación produce errores, se omite todo el procesamiento y se devuelve la página al usuario. Los controles de validación que detectan errores generan un mensaje de error que aparece en la página. Puede mostrar todos los errores de validación en un solo lugar mediante un control ValidationSummary. Nota: Los controles enlazados a datos que actualizan, insertan y eliminan datos, como los controles GridView, FormView y DetailsView, comprueban automáticamente si se han realizado las comprobaciones de validación antes de realizar una operación de actualización de datos. Cuándo se produce la validación Los controles de validación ejecutan la comprobación de los datos introducidos en el código del servidor. Cuando el usuario envía una página al servidor, los controles de validación se invocan para comprobar los datos introducidos por el usuario, control a control. Si se detecta un error de validación en uno de los controles de entrada de datos, la propia página se establece en un estado no válido para que se pueda probar la validez antes de ejecutar el código. La validación se produce después de la inicialización de la página (es decir, después de que el estado de vista y los datos devueltos se hayan procesado) pero antes de llamar a los controladores de eventos Change o Click. Si el usuario está trabajando con un explorador compatible con ECMAScript (Javascript), los controles de validación también pueden realizar la validación mediante secuencias de comandos del cliente. Esto puede mejorar el tiempo de respuesta de la página, ya que los errores se detectan inmediatamente y los mensajes de error se muestran en cuanto el usuario abandona el control que contiene el error. Si la validación está disponible en el cliente, se obtiene más control sobre la presentación de los mensajes de error y se puede mostrar un resumen de errores en un cuadro de mensaje. ASP.NET ejecuta una validación en el servidor aunque los controles de validación la hayan ejecutado en el cliente, por lo que se puede probar la validez en los controladores de eventos basados en el servidor. Además, la nueva comprobación en el servidor ayuda a evitar que los usuarios puedan omitir la validación deshabilitando o cambiando la secuencia de comandos del cliente. Si se desea, se puede invocar la validación en su propio código llamando al método Validate de un control de validación. Validar múltiples condiciones Cada control de validación normalmente realiza una comprobación. No obstante, es posible que se deseen comprobar múltiples condiciones. Por ejemplo, se desea especificar que una entrada de usuario es necesaria y que sólo puede contener fechas dentro de un intervalo especificado. En las páginas se puede asociar más de un control de validación a cada control de entrada. En ese caso, las comprobaciones realizadas por los controles se resuelven utilizando un operador lógico AND, lo que significa que los datos introducidos por el usuario deben pasar todas las comprobaciones para que se consideren válidos. En algunos casos podrían ser entradas válidas en varios formatos distintos. Por ejemplo, si se solicita un número de teléfono, se puede permitir que los usuarios introduzcan un número local, un número de larga distancia o un número internacional. El uso de múltiples controles de validación no funcionaría en esta instancia, ya que los datos introducidos por el usuario deben pasar todas las comprobaciones para ser válidos. Para realizar este tipo de comprobación, que es una operación lógica OR en la que sólo se debe 65 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 pasar una comprobación, se utiliza el control de validación RegularExpressionValidator y se deben especificar múltiples modelos válidos en el control. Opcionalmente, se puede utilizar el control de validación CustomValidator y escribir el propio código de validación. Mostrar la información de errores Normalmente, los controles de validación no son visibles en la página presentada. No obstante, si el control detecta un error, muestra el texto del mensaje de error que se especifique. El mensaje de error se puede mostrar de formas diferentes: En contexto: Cada control de validación puede mostrar su propio mensaje de error en contexto (normalmente junto al control donde se ha producido el error). Resumen: Los errores de validación pueden recopilarse y mostrarse en un lugar, por ejemplo, en la parte superior de la página. Esta estrategia se utiliza a menudo junto con la presentación de un mensaje al lado de los campos de entrada con errores. Si el usuario trabaja con Internet Explorer 4.0 o posterior, el resumen puede mostrarse en un cuadro de mensaje. Si se utiliza grupos de validación, se necesita un control ValidationSummary para cada uno de ellos. En contexto y en un resumen: El mensaje de error puede ser diferente en el resumen y en contexto. Puede utilizar esta opción para mostrar un mensaje de error más corto en el contexto y con más detalles en el resumen. Personalizado: Puede personalizar la presentación del mensaje de error capturando la información de error y diseñando su propio resultado. Si se utiliza las opciones de presentación en contexto o en un resumen, se puede dar formato al texto del mensaje de error mediante HTML. Nota de seguridad: Si se crean mensajes de error personalizados, asegúrarse de no mostrar información que pudiera ayudar a un usuario malintencionado a poner en peligro la aplicación. Modelo de objetos de validación El modelo de objetos expuesto por cada uno de los controles de validación y por la página permite interactuar con los controles de validación. Cada control de validación expone su propiedad IsValid, que se puede probar para determinar si se ha pasado la comprobación de validación o ha producido errores en ese control. La página también expone una propiedad IsValid que resume el estado IsValid de todos los controles de validación de la página. Esta propiedad le permite realizar una única comprobación para determinar si puede continuar con su propio procesamiento. La página también expone una colección Validators que contiene una lista de todos los controles de validación de la página. Puede recorrer esta colección para examinar el estado de controles de validación individuales. Personalizar la validación El proceso de validación se puede personalizar de las maneras siguientes: Especificar el formato, el texto y la ubicación de los mensajes de error. Además, se puede especificar si los mensajes de error aparecen de forma individual o como un resumen. Crear validación personalizada utilizando el control CustomValidator. El control llama a la lógica personalizada, pero, por lo demás, funciona de la misma manera que otros controles de validación al establecer el estado de error, mostrar los mensajes de error, etc. Esto proporciona una forma fácil de crear una lógica de validación personalizada, pero sin dejar de utilizar el marco de trabajo de validación de la página. En la validación en el cliente, interceptar la llamada a la validación y sustituir o agregar su propia lógica de validación. TIPOS DE VALIDACIÓN Y CONTROLES Tipo de validación Utilizar control Entrada RequiredFieldValidator Descripción Garantiza que el usuario no omite una entrada. requerida. Comparación con CompareValidator Compara los datos proporcionados por el usuario con un valor constante, con el valor un valor de otro control (mediante un operador de comparación como menor que, igual que o 66 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 mayor que) o para un tipo de datos específico. Comprobación RangeValidator del intervalo Comprueba que una entrada de usuario está entre los límites superior e inferior especificados. Se pueden comprobar los intervalos entre pares de números, caracteres alfabéticos y fechas. Coincidencia de RegularExpressionValidator Comprueba que la entrada del usuario coincide con un modelo definido por una modelos expresión regular. Este tipo de validación permite comprobar secuencias de caracteres predecibles, como los que aparecen en las direcciones de correo electrónico, números de teléfono, códigos postales, etc. Definida por el CustomValidator usuario Comprueba la entrada de usuario utilizando la validación lógica que ha escrito. Este tipo de validación permite comprobar valores derivados en tiempo de ejecución. 12 UTILIZAR CONTROLES ESTÁNDAR: BUTTON, TEXTBOX, DROPDOWNLIST, RADIOBUTTON, CHECKBOX, HYPERLINK, WIZARD, MULTIVIEW Los controles estándar son los controles de servidor Web ASP.NET que aparecen en la ficha Estándar del cuadro de herramientas de Visual Web Developer. Entre ellos se incluyen controles que permiten mostrar botones, listas, imágenes, cuadros, hipervínculos, etiquetas o tablas, así como controles más complejos que trabajan con datos estáticos y dinámicos, o controles que actúan como contenedores de otros controles. BUTTON Mediante los controles Button de servidor Web de ASP.NET, las páginas Web ASP.NET permiten a los usuarios indicar que han finalizado el formulario o que desean ejecutar un comando concreto. Los controles de servidor Web incluyen tres tipos de botones, cada uno de los cuales aparece de manera diferente en las páginas Web. Tipos de botones En la tabla siguiente se muestran los tipos de botones que se pueden crear mediante los controles de servidor Web. Control Control Descripción Button de Presenta un botón de comando estándar, que se representa como un elemento input HTML. servidor Web Control LinkButton de Se representa como un hipervínculo en la página. No obstante, contiene una secuencia de comandos del servidor Web lado cliente que hace que el formulario se devuelva al servidor. (Se Puede crear un hipervínculo real mediante el control HyperLink de servidor Web.) Control ImageButton Permite especificar un gráfico como botón. Esto es útil para representar los botones con una apariencia más de servidor Web rica. Los controles ImageButton determinan con precisión el punto en el que hizo clic el usuario, lo que permite utilizar el botón como si fuera un mapa de imagen. TextBox El control de servidor Web TextBox proporciona a los usuarios un medio para escribir datos en una página Web ASP.NET, incluidos texto, números y fechas. DropDownList 67 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 El control DropDownList de servidor Web permite a los usuarios seleccionar uno o varios elementos de una lista predefinida. Se diferencia del control ListBox de servidor Web en que la lista de elementos permanece oculta hasta que los usuarios hacen clic en el botón desplegable. Además, el control DropDownList difiere del control ListBox en que no admite el modo de selección múltiple. RadioButton Los controles RadioButton y RadioButtonList permiten a los usuarios seleccionar opciones de entre un pequeño conjunto de opciones predefinidas mutuamente excluyentes. Se puede utilizar los controles CheckBox y CheckBoxList para hacer lo siguiente: Generar una devolución de datos de página cuando se selecciona un botón de opción. Capturar la interacción del usuario cuando un usuario selecciona un botón de opción. Enlazar cada botón de opción a los datos de una base de datos. CheckBox Se Puede utilizar dos tipos de controles de servidor Web para agregar casillas de verificación a una página de formularios Web Forms: controles CheckBox individuales o un control CheckBoxList. Ambos controles proporcionan a los usuarios la posibilidad de introducir datos de tipo Boolean: verdadero o falso (true o false), sí o no (yes o no). Nota: También se puede utilizar el control HtmlInputCheckBox para agregar casillas de verificación a una página de formularios Web Forms. Se puede agregar controles CheckBox individuales a una página y utilizarlos por separado. En cambio, el control CheckBoxList es un control único que actúa como control primario para una colección de elementos de lista de casillas de verificación. Este control proviene de una clase base ListControl y, por consiguiente, funciona como los controles de servidor Web ListBox, DropDownList, RadioButtonList y BulletedList. Por esta razón, muchos de los procedimientos para trabajar con el control CheckBoxList son los mismos que se utilizan para otros controles de lista de servidor Web. Cada tipo de control tiene sus ventajas. Al utilizar controles CheckBox individuales, tendrá mayor control sobre la distribución de las casillas de verificación en la página que si utiliza el control CheckBoxList. Por ejemplo, puede incluir texto (es decir, texto no perteneciente a casillas de verificación) entre las casillas de verificación. También puede controlar la fuente y el color de cada casilla de verificación. El control CheckBoxList es preferible si se desea crear una serie de casillas de verificación a partir de los datos de una base de datos. (También se puede enlazar un control CheckBox individual a datos.) HyperLink El control HyperLink de servidor Web crea vínculos en una página Web que permiten a los usuarios moverse por las páginas de una aplicación. La principal ventaja de utilizar un control HyperLink es que es posible establecer las propiedades de los vínculos en el código del servidor. Por ejemplo, se puede cambiar dinámicamente el texto del vínculo o la página de destino basándose en las condiciones de la página. Las direcciones URL asociadas con un hipervínculo pueden ser manipuladas por algún usuario malintencionado. Otra ventaja de utilizar el control HyperLink es que se puede utilizar el enlace de datos para especificar la dirección URL de destino del vínculo (y los parámetros que se transferirán con el vínculo, si es necesario). Un ejemplo típico es la creación de controles HyperLink basados en una lista de productos: la dirección URL apunta a una página en la que el usuario puede ver más detalles acerca del producto. Si se necesita crear controles HyperLink enlazados a datos, una manera conveniente de hacerlo es agregarlos como elementos secundarios de estos controles: Repeater, DataList, GridView, FormView o DetailsView. 68 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 El control HyperLink puede mostrar texto o una imagen en los que es posible hacer clic. A diferencia de la mayoría de controles de servidor Web, el control HyperLink no desencadena un evento en el código de servidor cuando el usuario hace clic en él. Este control simplemente desempeña tareas de desplazamiento. Wizard La recopilación de los datos proporcionados por el usuario a través de formularios es una tarea recurrente en el desarrollo de páginas Web. Un grupo de formularios que se utiliza para llevar a cabo una tarea se suele denominar asistente. ASP.NET proporciona un control Wizard que simplifica muchas de las tareas asociadas con la creación de un conjunto de formularios para recopilar los datos proporcionados por el usuario. Una práctica frecuente consiste en crear un grupo de formularios interconectados con el fin de dividir la recopilación de los datos. Para llevar a cabo esta tarea, puede administrar la exploración entre los formularios, la persistencia de los datos y la administración de estados en cada paso. El control Wizard de ASP.NET simplifica muchas de las tareas asociadas a la creación de varios formularios y la recopilación de los datos proporcionados por el usuario. El control Wizard proporciona un sencillo mecanismo que permite crear y agregar pasos o reordenar los pasos existentes con facilidad. Se puede crear exploraciones lineales y no lineales, así como personalizar la exploración del usuario del control sin necesidad de escribir código. MultiView Los controles MultiView y View de servidor Web actúan como contenedores para otros controles y el marcado, y proporcionan un medio para presentar de forma sencilla vistas alternativas de la información. Se puede utilizar los controles MultiView y View para realizar tareas como las siguientes: Proporcionar conjuntos de controles alternativos basados en la elección del usuario o en otras condiciones. Por ejemplo, se podría permitir a los usuarios hacer su selección en una lista de suministros, cada uno de los cuales estaría configurado en un control View diferente. A continuación, podría mostrar el control View que contiene la elección de suministros del usuario. Se puede utilizar los controles MultiView y View como alternativa para no crear varios controles Panel. Crear un formulario de varias páginas. Los controles MultiView y View pueden tener un comportamiento similar al del control Wizard. El control Wizard resulta especialmente apropiado para crear formularios que los usuarios rellenan paso a paso. El control Wizard también es compatible con otros elementos integrados de la interfaz de usuario, como un encabezado y pie de página, con los botones Anterior y Siguiente, y con las plantillas. Podría utilizar un control MultiView en lugar de un control Wizard si deseara crear una presentación que cambiara en función de una condición (y no de forma secuencial) o si no necesitara utilizar las características adicionales admitidas por el control Wizard. El control MultiView actúa como un contenedor externo para uno o varios controles View. Los controles View, a su vez, pueden contener cualquier combinación de marcado y controles. El control MultiView muestra un control View por vez, y expone también el marcado y los controles incluidos en ese control View. Al definir la propiedad ActiveViewIndex del control MultiView, puede especificar qué control View está visible actualmente. 13 LEER Y ESCRIBIR DATOS XML: XMLDOCUMENT, XPATHNAVIGATOR, XPATHNODEITERATOR, XPATHDOCUMENT, XMLREADER, XMLWRITER, XMLDATADOCUMENT, XMLNAMESPACEMANAGER XmlDocument (System.Xml) La clase XmlDocument implementa las interfaces de nivel 1 principal y de nivel 2 principal del DOM de W3C para leer y crear documentos XML. Esta clase implementa el Core Document Object Model (DOM) Level 1 y el Core DOM Level 2 del consorcio W3C. DOM es la representación en forma de árbol en memoria (caché) de un documento XML y permite la navegación y edición del documento. 69 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Dado que XmlDocument implementa la interfaz IXPathNavigable, también se puede utilizar como documento de origen de la clase XslTransform. XPathNavigator (System.Xml.XPath) La clase XPathNavigator ofrece numerosas opciones de edición y funciones de navegación por XML para un XmlDocument o un XPathDocument XPathNodeIterator (System.Xml.XPath) Proporciona un iterador para un conjunto seleccionado de nodos. XPathDocument (System.Xml.XPath) Proporciona una representación en memoria rápida y de solo lectura de un documento XML, utilizando el modelo de datos de XPath. XmlReader (System.Xml) La clase XmlReader proporciona un método rápido, sin almacenamiento en caché y sólo de avance (hacia adelante) para obtener acceso a los datos XML. XmlWriter (System.Xml) La clase XmlWriter proporciona un método rápido, sin almacenamiento en caché y de sólo avance (hacia adelante) para generar datos XML. XmlDataDocument (System.Xml) La clase XmlDataDocument extiende XmlDocument y permite que los datos estructurados se almacenen, recuperen y manipulen mediante un DataSet relacional. Esta clase permite que los componentes combinen vistas XML y relacionales de los datos subyacentes. XmlDataDocument tiene una relación estrecha con la clase DataSet que proporciona una vista relacional de los datos XML cargados. Los cambios efectuados en XmlDataDocument se reflejan en DataSet y viceversa. Para cargar DataSet con datos XML, se utiliza ReadXmlSchema para generar una asignación relacional. A continuación, los datos XML se pueden cargar mediante Load o LoadXml. XmlNamespaceManager (System.Xml) Resuelve, agrega y quita espacios de nombres en una colección y proporciona la administración del ámbito de estos espacios de nombres. 70 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 14 MANIPULAR LOS DATOS UTILIZANDO LOS OBJETOS DATASET Y DATAREADER ARQUITECTURA DE ADO.NET DataSet El DataSet de ADO.NET es una representación de datos residente en memoria que proporciona un modelo de programación relacional coherente independientemente del origen de datos que contiene. Un DataSet representa un conjunto completo de datos, incluyendo las tablas que contienen, ordenan y restringen los datos, así como las relaciones entre las tablas. Hay varias maneras de trabajar con un DataSet, que se pueden aplicar de forma independiente o conjuntamente. Se puede: Crear mediante programación una DataTable, DataRelation y una Constraint en un DataSet y rellenar las tablas con datos. Llenar el DataSet con tablas de datos de un origen de datos relacional existente mediante DataAdapter. Cargar y hacer persistente el contenido de DataSet mediante XML. También se puede transportar un DataSet con establecimiento inflexible de tipos mediante un servicio web XML. El diseño del DataSet lo convierte en idóneo para el transporte de datos mediante servicios web XML. Data Reader Recuperar datos mediante DataReader (ADO.NET) La recuperación de datos mediante DataReader implica crear una instancia del objeto Command y de un DataReader a continuación, para lo cual se llama a Command.ExecuteReader a fin de recuperar filas de un origen de datos. En el ejemplo siguiente se muestra cómo se utiliza un DataReader, donde reader representa un DataReader válido y command representa un objeto Command válido. 71 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 rreader = command.ExecuteReader(); Se Puede utilizar el método Read del objeto DataReader para obtener una fila a partir de los resultados de una consulta. Para tener acceso a cada columna de la fila devuelta, puede pasar a DataReader el nombre o referencia numérica de la columna en cuestión. Sin embargo, el mejor rendimiento se logra con los métodos que ofrece DataReader y que permiten tener acceso a los valores de las columnas en sus tipos de datos nativos (GetDateTime, GetDouble, GetGuid, GetInt32, etc). Los datareaders dependen de proveedores de datos específicos como por ejemploOleDbDataReader y SqlDataReader. Si se utilizan los métodos de descriptor de acceso con tipo, dando por supuesto que se conoce el tipo de datos subyacentes, se reduce el número de conversiones de tipo necesarias para recuperar el valor de una columna. DataReader (ADO.Net) Se puede utilizar el DataReader de ADO.NET para recuperar secuencias de datos de sólo lectura y sólo avance de una base de datos. Los resultados se devuelven a medida que se ejecuta la consulta y se almacenan en el búfer de red del cliente hasta que se solicitan con el método Read del DataReader. Con el DataReader puede aumentar el rendimiento de la aplicación tanto al recuperar datos en cuanto están disponibles como al almacenar (de forma predeterminada) una fila cada vez en memoria, lo que reduce la sobrecarga del sistema. Cada proveedor de datos de .NET Framework incluido en .NET Framework cuenta con un objeto DataReader: el proveedor de datos de .NET Framework para OLE DB incluye un objeto OleDbDataReader, el proveedor de datos de .NET Framework para SQL Server incluye un objeto SqlDataReader, el proveedor de datos de .NET Framework para ODBC incluye un objeto OdbcDataReader y el proveedor de datos de .NET Framework para Oracle incluye un objeto OracleDataReader. 15 LLAMAR A UN SERVICIO WINDOWS COMMUNICATION FOUNDATION (WCF) O A UN SERVICIO WEB DESDE UNA PÁGINA WEB ASP.NET: APP_WEBREFERENCES; <SYSTEM.SERVICEMODEL> CONFIGURATION CONSUMO DE SERVICIOS WCF El escenario de alojamiento elegido para el servicio WCF puede influir en el lado del consumidor. Se puede consumir los servicios WCF de varias maneras. Si se usa WCF en el lado del cliente será muy productivo, ya que WCF incluye herramientas que pueden generar clases de proxy para llamar a los servicios WCF. WCF proporciona compatibilidad con los estándares y las herramientas principalmente a través de SvcUtil.exe. Lo usará como herramienta principal de interpretación de metadatos. Eso, en combinación con la capacidad de Framework de WCF para aprovechar la reflexión para interrogar tipos adornados con los atributos apropiados, hace la generación y el uso de Framework de WCF menos complicado que con los marcos existentes. Además, Visual Studio 2005 incluye sencillas características para agregar referencias al servicio a sus proyectos y generar continuamente clases de proxy. Esencialmente, dispone de las siguientes opciones: Recuperar el WSDL del servicio y crear un proxy para llamar al servicio. Éste es un escenario típico si no se cuenta con WCF en el lado del cliente. Usar las características Add Service Reference de Visual Studio 2005 y dejar que genere un proxy que usar en el cliente. Use la herramienta SvcUtil.exe para generar clases de proxy. En las secciones siguientes, estudiaremos las dos últimas opciones: Visual Studio 2005 y SvcUtil.exe. Proxy de servicio Un proxy de servicio permite trabajar con servicios de una manera orientada a objetos. Las clases de proxy abstraen el modelo de comunicación usado por el servicio, como desarrollador de cliente se abstrae el hecho de que habla con un servicio (remoto). Es como si se llamase al código local. La clase de proxy implementa la interfaz del servicio y, por tanto, permite llamar a los métodos en la interfaz del servicio, como si éstos fueran métodos locales. Los proxy se generan para algún tipo personalizado utilizado en la interfaz de servicio. El siguiente código contiene partes de un proxy generado para el servicio TradeService ilustrando que, en el lado del cliente, hay disponible una Quote que se asigna al objeto Quote en el lado del servidor, aunque se trate de clases distintas. El objeto Quote serializa según el contrato, de modo que, en el lado del servicio, se serializa en la versión del lado del servicio del contrato de datos Quote. Además, se puede consultar los métodos GetQuote y PlaceQuote llamando a una clase base que hará finalmente la llamada a través del límite del servicio por medio del transporte configurado. 72 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 namespace SimpleClientWithProxy.ExchangeService { [DataContract()] public partial class Quote : object, IExtensibleDataObject { // Left out the Quote Datamembers in printed code, see sample code } } [GeneratedCode("System.ServiceModel", "3.0.0.0")] [ServiceContract()] public interface ITradeService { [ OperationContract(Action = "http://tempuri.org/ITradeService/GetQuote", ReplyAction = "http://tempuri.org/ITradeService/GetQuoteResponse")] Quote GetQuote(string ticker); [ OperationContract(Action = "http://tempuri.org/ITradeService/PublishQuote", ReplyAction = "http://tempuri.org/ITradeService/PublishQuoteResponse")] void PublishQuote(Quote quote); } [GeneratedCode("System.ServiceModel", "3.0.0.0")] public interface ITradeServiceChannel : ITradeService, IClientChannel { } [GeneratedCode("System.ServiceModel", "3.0.0.0")] public partial class TradeServiceClient : ClientBase<ITradeService>, ITradeService { // Left out some constructors in printed code, see sample code public SimpleClientWithProxy.ExchangeService.Quote GetQuote(string ticker) { return base.Channel.GetQuote(ticker); } } public void PublishQuote( SimpleClientWithProxy.ExchangeService.Quote quote) { base.Channel.PublishQuote(quote); } Uso de Visual Studio 2005 De forma similar al caso de la creación de proxy ASP.NET, si hace clic con el botón secundario en el proyecto del IDE, aparecerán tres opciones para agregar referencias. 73 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 La opción es Add Service Reference. Esta opción del menú es un contenedor de la utilidad SvcUtil.exe, que genera un proceso con los parámetros necesarios. Una vez que haya seleccionado Add Service Reference, aparecerá el siguiente cuadro de diálogo. Una vez que hecho clic en Aceptar en el cuadro de diálogo, el complemento genera SvcUtil.exe, que crea la clase de proxy necesaria y el archivo de configuración requerido (o lo modifica) y agrega las referencias necesarias al proyecto. Las referencias del proyecto ahora enumerarán los ensamblados de WCF. Nota Para que esto funcione, ServiceHost de Windows debe estar en ejecución o debe cambiar la URL para señalar a cualquiera de los servicios alojados en IIS (una dirección URL que señala a cualquiera de los archivos .svc). Ahora es posible programar la primera llamada a servicio en su nivel de servicio. Implementación de línea de comandos Un método alternativo es aprovechar la utilidad SvcUtil.exe directamente en lugar del complemento de Visual Studio. De nuevo, el complemento de Visual Studio llama a SvcUtil.exe, con parámetros, para generar el proxy cuando se ejecuta directamente desde Visual Studio. Se puede ver la línea de comandos y los resultados de ese comando consultando la ventana Resultado y estableciendo Show output en la lista desplegable en Service Reference. Para una generación manual, se elija la ventana CMD seleccionando Inicio | Todos los programas | Microsoft Windows SDK | CMD. Este símbolo del sistema es útil porque su ruta de acceso está establecida en el directorio binario donde se encuentran las herramientas y utilidades del SDK. Se usará la herramienta de línea de comandos SvcUtil.exe para generar dos resultados que podrían usarse en el proyecto SimpleClientWithProxy. No obstante, en el código de ejemplo incluido en este capítulo se usó el método Add Service Reference descrito en la sección anterior. Los pasos aquí descritos explican cómo generar los mismos resultados que Add Service Reference. Los archivos de resultados son el archivo de código fuente del proxy de cliente y el archivo de configuración de la aplicación. Estos 74 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 archivos se integran en el proyecto cliente. SvcUtil.exe puede generar ambos. Para este ejemplo, el comando siguiente (es una sola línea, a pesar de cómo queda dispuesto en la imagen) produce tanto una clase de proxy como un archivo de configuración: svcutil /config:app.config /out:"ExchangeService.cs" /language:csharp /n:*, SimpleClientWithProxy.ExchangeService "http://localhost/ExchangeService/? ExchangeService.svc" Nota Para que esto funcione, se necesita una versión en ejecución de ServiceHost de Windows, o se debe cambiar la dirección URL para señalar a cualquiera de los servicios alojados en IIS (una dirección URL que señala a cualquiera de los archivos .svc tratados en este capítulo). El comando se explica por sí mismo. El modificador /n indica bajo qué espacio de nombres debería ubicarse la clase de proxy generada. El último parámetro es la dirección URL del extremo del servicio donde se encuentra la información de esquema. Tener en cuenta que ?wsdl se puede reemplazar con ?mex, ya que SvcUtil.exe admite ambos métodos de descubrimiento. Se puede obtener más ayuda ejecutando svcutil.exe/? desde el símbolo del sistema. El paso siguiente es tomar los archivos de resultados Exchangeservice.cs y App.config, e integrarlos en el proyecto. Se puede agregar sólo el primer archivo, Exchangeservice.cs, directamente al proyecto eligiendo Agregar elemento existente en el menú Proyecto de Visual Studio 2005. Se debe agregar al proyecto el segundo archivo como archivo de configuración de aplicación (App.config). Si el proyecto no cuenta ya con un archivo App.config, lo podrá agregar seleccionando de nuevo Agregar elemento existente en el menú Proyecto. Si ya existe un archivo App.config, se debe unir la sección system.serviceModel, asegurándose de tomar todos los elementos secundarios adecuados. SERVICIOS WEB Agregar y quitar referencias Web Una referencia Web habilita un proyecto para que utilice uno o más servicios Web XML. Utilizar el Agregar referencia Web (Cuadro de diálogo) para buscar servicios Web localmente, en una red de área local o en Internet. Después de agregar una referencia Web al proyecto actual, puede llamar a cualquier método expuesto por el servicio Web. Para agregar una referencia Web a un proyecto 1. En el Explorador de soluciones, clic con el botón secundario del mouse en el nombre del proyecto al que va a agregar el servicio Web y, a continuación, clic en Agregar referencia Web. Aparece el cuadro de diálogo Agregar referencia Web. 2. En el cuadro Dirección URL, escribir la dirección URL del servicio Web que va a utilizar. Se pueden utilizar los vínculos del panel de exploración para buscar el servicio Web. Nota: Si se está desarrollando una aplicación Web en un equipo protegido por un firewall y la aplicación va a utilizar servicios Web situados fuera de ese firewall, es preciso incluir en la dirección URL la dirección y el puerto del servidor proxy de la red. Solicitar al administrador de red facilitar esta parte de la ruta de acceso de la dirección URL. 3. En el cuadro Servicios Web disponibles en esta dirección URL, seleccionar el servicio Web que va a utilizar. 4. Comprobar que el proyecto puede utilizar el servicio Web y que cualquier código externo proporcionado es de confianza. Nota de seguridad: Cuando se abre un proyecto para editarlo y éste incluye una referencia Web, un archivo local del proxy correspondiente al servicio Web utilizado se ejecutará en un proceso de Devenv.exe iniciado por un usuario de confianza: el propio usuario. Al abrir proyectos o componentes en el entorno de desarrollo integrado (IDE), puede que se ejecute código en el equipo local. 5. En el campo Nombre de referencia Web escribir el nombre que luego vaya a utilizar en el código para obtener acceso mediante programación al servicio Web seleccionado. Nota: De forma predeterminada, a las referencias Web se les asigna un espacio de nombres que corresponde al nombre del servidor. Se puede cambiar este valor y escribir un nombre de espacio de nombres personalizado. Hay algunas limitaciones en 75 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 cuanto a los nombres de espacio de nombres aceptados. Visual Web Developer crea un espacio de nombres basado en el nombre de la referencia Web, generando una jerarquía de carpetas anidada. Dentro de la carpeta más interna se crea un archivo .wsdl que hace referencia al servicio Web, además de otros archivos auxiliares, como archivos de descubrimiento (.disco y .discomap), que incluyen información sobre dónde se encuentra el servicio Web. 6. Clic en Agregar referencia. Si el sitio Web no tiene todavía una, Visual Studio creará una carpeta App_WebReferences. Quitar una referencia Web Si el proyecto ya no necesita una referencia a un servicio Web XML, se puede quitar del mismo. En el Explorador de soluciones, Clic con el botón secundario del mouse en la referencia Web y, a continuación, Clic en Eliminar. Toda la información de referencia se quita del proyecto y del almacenamiento local. Invocar a un servicio Web Después de agregar al proyecto una referencia Web al servicio Web XML, se puede utilizar el nombre del servidor para crear un objeto proxy que permita llamar a los métodos en un servicio Web XML. Para llamar a un servicio Web mediante programación se utiliza el nombre de la referencia Web (o nombre del servidor) como espacio de nombres y el nombre del archivo .WSDL (o nombre del servicio) como la clase de proxy. El ejemplo de código siguiente llama a un método de servicio Web para obtener un valor de cadena. void Call_Web_Service_Method() { ServerName.WebServiceNameCallWebService = new ServerName.WebServiceName(); String sGetValue = CallWebService.MethodName(); Label1.Text = sGetValue; } 16 IMPLEMENTAR UN CONTROL DATASOURCE: LINQDATASOURCE, OBJECTDATASOURCE, XMLDATASOURCE, SQLDATASOURCE ASP.NET incluye controles de origen de datos que permiten trabajar con distintos tipos de orígenes de datos, como bases de datos, archivos XML u objetos comerciales de nivel medio. Los controles de origen de datos se conectan a un origen de datos para recuperar datos y permiten a otros controles enlazarse a ellos, sin necesidad de código. También admiten la modificación de datos. Esta tema ofrece información sobre los distintos tipos de controles de origen de datos en ASP.NET. El modelo de control de origen de datos es ampliable, por lo que también puede crear sus propios controles de origen de datos que interactúen con orígenes de datos diferentes o que proporcionen funcionalidad adicional para un origen de datos existente. Comparación de controles de origen de datos .NET Framework incluye controles de origen de datos que admiten el uso de distintos escenarios de enlace de datos. En la tabla siguiente se describen los controles de origen de datos integrados. LinqDataSource 76 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Permite usar Language-Integrated Query (LINQ) en una página web ASP.NET a través de marcado declarativo para recuperar y modificar datos de un objeto de datos. Admite la generación automática de comandos de selección, actualización, inserción y eliminación. El control también admite ordenación, filtrado y paginación. El control LinqDataSource permite usar LINQ en una página ASP.NET para recuperar datos de una tabla de base de datos o de una recolección de datos en memoria. Se puede usar marcado declarativo para escribir todas las condiciones que se requieren para recuperar, filtrar, ordenar y agrupar los datos. Si se recupera datos de una tabla de base de datos SQL, también se puede configurar un control LinqDataSource para administrar las operaciones de actualización, inserción y eliminación. Se puede escribir comandos SQL para realizar estas tareas. Si se usa el control LinqDataSource, se puede reducir la cantidad de código necesario para las operaciones de datos, en comparación con las mismas operaciones en otros controles de origen de datos. EntityDataSource Permite enlazar a datos basados en Entity Data Model (EDM). Admite la generación automática de comandos de actualización, inserción, eliminación y selección. El control también admite la ordenación, el filtrado y la paginación. El control EntityDataSource admite escenarios de enlace de datos basados en Entity Data Model (EDM). Esta especificación de datos representa los datos como conjuntos de entidades y relaciones. Entity Framework usa el EDM en asignaciones relacionales de objetos y otros escenarios como Servicios de datos de ADO.NET. El control EntityDataSource admite Entity-SQL (eSQL) como el lenguaje de la consulta y también la especificación de la consulta que muestra la clase ObjectQuery<T>. ObjectDataSource Permite trabajar con un objeto comercial u otra clase y crear aplicaciones Web basadas en objetos de nivel medio para administrar los datos. Admite ordenación avanzada y escenarios de paginación no disponibles con los otros controles de origen de datos. El control ObjectDataSource trabaja con un objeto comercial u otra clase en las aplicaciones Web basadas en objetos comerciales de nivel medio para administrar datos. El control está diseñado para interactuar con un objeto que implementa uno o varios métodos a fin de recuperar o modificar datos. Cuando los controles enlazados a datos interactúan con el control ObjectDataSource para recuperar o modificar datos, dicho control pasa los valores del control enlazado al objeto de origen como parámetros de llamadas a métodos. Los métodos de recuperación de datos del objeto de origen deben devolver un objeto DataSet, DataTable o DataView, o un objeto que implemente la interfaz IEnumerable. Si los datos se devuelven como un objeto DataSet, DataTable o DataView, el control ObjectDataSource puede almacenar datos en caché y filtrarlos. También es posible implementar escenarios de paginación avanzados si el objeto de origen acepta la información de tamaño de página y de índice de registro del control ObjectDataSource. SqlDataSource Permite trabajar con bases de datos de Microsoft SQL Server, OLE DB, ODBC u Oracle. Cuando se utiliza con SQL Server, admite funciones de almacenamiento en caché avanzadas. Este control también admite ordenación, filtrado y paginación cuando los datos se devuelven como un objeto DataSet. El control SqlDataSource recupera y modifica datos utilizando comandos SQL. El control SqlDataSource funciona con bases de datos de Microsoft SQL Server, OLE DB, ODBC y Oracle. El control SqlDataSource puede devolver los resultados en forma de objeto DataReader o DataSet. Admite ordenación, filtrado y almacenamiento en caché cuando los resultados se devuelven como un objeto DataSet. Cuando se trabaja con Microsoft SQL Server, el control tiene la ventaja adicional de que los resultados de la caché se pueden invalidar cuando se modifica la base de datos, utilizando un objeto SqlCacheDependency. AccessDataSource Permite trabajar con una base de datos de Microsoft Access. Admite ordenación, filtrado y paginación cuando los datos se devuelven como un objeto DataSet. 77 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 XmlDataSource Permite trabajar con un archivo XML, especialmente para los controles de servidor ASP.NET como TreeView o Menu. Admite funciones de filtrado mediante expresiones XPath y permite aplicar una transformación XSLT a los datos. El control XmlDataSource permite actualizar los datos al guardar el documento XML completo con cambios. El control XmlDataSource lee y escribe datos XML, lo que permite trabajar con ellos mediante controles como TreeView y Menu. El control XmlDataSource puede leer un archivo XML o una cadena de XML. Si el control está trabajando con un archivo XML, puede escribir el código XML modificado en el archivo de código fuente. Si hay un esquema disponible que describe los datos, el control XmlDataSource puede utilizarlo para exponer los datos mediante miembros con tipo. Se Puede aplicar una transformación XSLT a los datos XML, lo que permitirá reestructurar los datos sin formato del archivo XML en un formato más apropiado para el control que desea enlazar con los datos XML. También se puede aplicar expresiones XPath a los datos XML, lo que le permitirá filtrar éstos para devolver únicamente ciertos nodos del árbol XML, buscar nodos con valores determinados, etc. El uso de una expresión XPath deshabilita la funcionalidad de insertar nuevos datos. SiteMapDataSource Se utiliza con la navegación en el sitio de ASP.NET. El control SiteMapDataSource funciona con los mapas de sitios ASP.NET y proporciona datos para la navegación en el sitio. Se suele utilizar con el control Menu. El control SiteMapDataSource también resulta útil cuando se desea personalizar la navegación en el sitio utilizando datos del mapa del sitio con controles de servidor Web que no están diseñados específicamente para la navegación, como los controles TreeView o DropDownList. 17 VINCULAR LOS CONTROLES A LOS DATOS UTILIZANDO LA SINTAXIS DE UNIÓN DE DATOS (DATA BINDING) EL MECANISMO DEL ENLACE A DATOS Para generar un nuevo control enlazado a datos en ASP.NET 2.0, se debe decidir previamente qué clase se adapta mejor a LAS necesidades. Esta decisión, sin embargo, no se limita a clases relativamente vacías como Control y WebControl o, quizá, ListControl. Examinando las clases en profundidad. BaseDataBoundControl es la raíz de todas las clases de controles enlazados a datos. Define las propiedades DataSource y DataSourceID y valida el contenido asignado de las mismas. DataSource acepta objetos enumerables que se obtienen y asignan del mismo modo que en ASP.NET 1.x. Mycontrol1.DataSource = dataSet; Mycontrol1.DataBind(); DataSourceID es una cadena y hace referencia al identificador de un componente de origen de datos. Una vez que un control se enlaza a un origen de datos, cualquier interacción posterior entre los dos (tanto en la lectura como en la escritura) queda fuera del control del programador y oculta a la vista. Este hecho muestra al mismo tiempo aspectos positivos y negativos. Una de las grandes ventajas consiste en que permite eliminar una gran cantidad de código. El marco de ASP.NET garantiza que se ejecuta el código correcto y que éste se escribe de acuerdo con las prácticas más adecuadas reconocidas. Permite una mayor productividad puesto que las páginas se crean con mayor rapidez al tener la absoluta seguridad de que no contienen ningún error. Si no es conveniente esta situación (observe que es la misma situación de la que se quejaban numerosos desarrolladores de ASP.NET 1.x) se puede seguir utilizando la programación convencional que pasa a través de la propiedad DataSource y el método DataBind. Asimismo, en este caso, la clase base evita el uso de prácticas habituales aunque el ahorro en el código no es tan notable. DataBoundControl es la clase que se utiliza para controles enlazados a datos estándares y personalizados que no comparten mucho con los controles existentes. Si se debe controlar la propia colección de elementos de datos, administrar viewstate y los estilos, crear una interfaz de usuario sencilla pero hecha a medida, esta clase ofrece un óptimo punto de partida. Más interesante resulta el hecho de que la clase DataBoundControl conecta el control con los componentes de origen de datos y oculta cualquier 78 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 diferencia entre los orígenes de datos enumerables y los componentes ad hoc en el nivel de la API. En resumen, cuando se hereda de esta clase sólo se necesita omitir un método que recibe una colección de datos independientemente del origen, ya sea un objeto DataSet o un componente de origen de datos más nuevo. BaseDataBoundControl omite el método DataBind (originalmente definido en Control) y lo hace llamar el método PerformSelect, que está marcado como protegido y abstracto. Como sugiere el nombre, PerformSelect debe recuperar una colección de datos operativa para que se realice el enlace. El método está protegido puesto que contiene detalles de la implementación y es abstracto (MustInherit en la jerga de Visual Basic) ya que su comportamiento sólo lo pueden precisar las clases derivadas como DataBoundControl. Así pues, ¿cómo actúa DataBoundControl para omitir PerformSelect? Se conecta al objeto de origen de datos y obtiene la vista predeterminada. Un objeto de origen de datos (por ejemplo, un control como SqlDataSource u ObjectDataSource) ejecuta el comando de selección y devuelve la colección resultante. El método protegido que lleva a cabo la recuperación de los datos, denominado GetData, es capaz de comprobar también la propiedad DataSource. Si DataSource no está vacío, el objeto enlazado se empaqueta en un objeto de vista de origen de datos creado dinámicamente y se devuelve. Con el siguiente paso comienza la intervención del desarrollador de controles. Hasta el momento, de una forma completamente automatizada, las clases base han recuperado los datos bien desde los objetos de ADO.NET o desde los componentes de origen de datos. El siguiente paso depende de la función que deba realizar el control. Aquí es donde interviene el método reemplazable PerformDataBinding. El siguiente fragmento de código muestra el método tal como se implementa en DataBoundControl. Observe que el parámetro IEnumerable que el marco pasa al método simplemente contiene los datos que se van a enlazar, independientemente del origen de los mismos. protected virtual void PerformDataBinding(IEnumerable data) { } En un control enlazado a datos personalizado, sólo se requiere omitir este método y rellenar todas las colecciones específicas del control como la colección Items de numerosos controles de lista (CheckBoxList, por ejemplo). El procesamiento de la interfaz de usuario del control se lleva a cabo en el método Render o en CreateChildControls, en función de la naturaleza del control. Render es adecuado para los controles de lista; CreateChildControls resulta la opción perfecta para los controles compuestos. Aún queda una cuestión por explicar: ¿quién inicia el proceso de enlace a datos? En ASP.NET 1.x, el enlace a datos requiere una llamada explícita al método DataBind para comenzar a funcionar. En ASP.NET 2.0, también se requiere esta llamada si se enlazan los datos a los controles mediante la propiedad DataSource. Sin embargo, se debería evitar si se utilizan componentes de origen de datos mediante la propiedad DataSourceID. El proceso de enlace a datos se activa automáticamente por el controlador de eventos interno OnLoad que se define en DataBoundControl, como se demuestra en el siguiente pseudocódigo. protected override void OnLoad(EventArgs e) { this.ConnectToDataSourceView(); if (!Page.IsPostBack) base.RequiresDataBinding = true; base.OnLoad(e); } 79 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Cuando el control se carga en la página (ya sea una devolución de datos o por primera vez), los datos se recuperan y se enlazan. El origen de datos es el que decide si continuar de nuevo con una consulta o utilizar datos almacenados en caché. Si la página se muestra por primera vez, se activa también la propiedad RequiresDataBinding para solicitar el enlace de los datos. Cuando el valor asignado es true, el establecedor de la propiedad llama a DataBind internamente. El pseudocódigo que aparece a continuación muestra la implementación interna del establecedor RequiresDataBinding. protected void set_RequiresDataBinding(bool value) { if (value & (DataSourceID.Length > 0)) DataBind(); else _requiresDataBinding = value; } Como se puede comprobar, para conseguir compatibilidad con versiones anteriores la llamada automática a DataBind se lleva a cabo únicamente si DataSourceID no es nulo, es decir, si se enlaza a un control de origen de datos de ASP.NET 2.0. Por lo tanto, si también se realiza una llamada a DataBind explícitamente, el resultado será un enlace doble de los datos. Observe que no se puede establecer al mismo tiempo DataSource y DataSourceID. Cuando esto ocurre, se obtiene una excepción de operación no válida. Por último, debemos mencionar brevemente el método protegido EnsureDataBound. Este método, que se define en la clase BaseDataBoundControl, garantiza que el control se ha enlazado correctamente a los datos necesarios. Si RequiresDataBinding se establece en true, el método invoca a DataBind, como en el siguiente fragmento de código. protected void EnsureDataBound() { if (RequiresDataBinding & (DataSourceID.Length > 0)) DataBind(); } En ASP.NET 1.x, un control enlazado a datos generalmente posee una arquitectura para generar su propia interfaz de usuario en uno de los dos escenarios siguientes: con acceso completo al origen de datos o basado en viewstate. Cuando el control debe administrar sus propios eventos de devolución de datos (por ejemplo, imaginemos un DataGrid con paginación activada), las dos opciones mencionadas anteriormente parecen ser dos simples extremos distantes. En ASP.NET 1.x, estos controles (pensemos de nuevo en DataGrid) sólo tenían una salida: activar los eventos en la página host para que se actualizaran. Este enfoque tiene como consecuencia el conocido exceso de código de las páginas de ASP.NET 1.x: precisamente el problema que los componentes de origen de datos se proponen solucionar. En ASP.NET 2.0, se establece RequiresDataBinding en true siempre que ocurre algo en la vida de un control que requiere el enlace de los datos. Al establecer la propiedad se activa el mecanismo del enlace a datos que vuelve a crear una versión actualizada de la infraestructura interna del control. El controlador de eventos integrado OnLoad conecta asimismo el control al origen de datos. Para que sea realmente eficaz, esta técnica se debe basar en unos controles de origen de datos inteligentes con capacidad para almacenar los datos en alguna parte de la memoria caché. El control SqlDataSource, por ejemplo, admite numerosas propiedades para almacenar cualquier conjunto de resultados enlazados en la caché de ASP.NET durante un período especificado. 80 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 18 CONFIGURAR LA DEPURACIÓN Y LOS ERRORES PERSONALIZADOS. PUEDE INCLUIR, PERO SIN LIMITARSE A ELLO: <customErrors mode="Off|On|RemoteOnly" />, <compilation debug="true"/> Para habilitar la depuración para una aplicación Web ASP.NET, se debe configurar la aplicación para que se compile en una versión de depuración. Una versión de depuración incluye información que el depurador necesita para poder recorrer el código y mostrar el contenido de las variables. La configuración de una aplicación Web para las versiones de depuración se realiza en la sección Compilation del archivo Web.config de la aplicación. Como alternativa, si sólo se desea depurar páginas individuales, puede agregar debug=true a la directiva @ Page en las páginas que desea depurar. Nota: Una aplicación compilada en una versión de depuración funcionará bastante más despacio que si se compila en una versión comercial. Asegurarse de desactivar el modo de depuración antes de implementar la aplicación. Además, en modo de depuración se expone más información en la pila cuando se produce un error y esto puede suponer un problema de seguridad. Depuración local y remota Si se está ejecutando un servidor Web localmente, como IIS, se puede depurar aplicaciones ejecutándose localmente en el equipo, de forma que se pueda ver las páginas en un explorador. Si no se puede ejecutar una página localmente, porque no se puede ejecutar un servidor Web o porque la aplicación no está disponible localmente, se puede depurar una aplicación que se ejecute en otro servidor. Para poder realizar la depuración de manera remota, debe instalar los componentes de depuración remota de Visual Studio en el servidor remoto. Permisos para la depuración La depuración de un proceso requiere más privilegios que su ejecución. Por tanto, además de configurar la aplicación para la depuración, se debe asegurar también de que se dispone de los permisos adecuados para asociarla a un proceso con el fin de depurarla. Los usuarios tienen permiso para depurar procesos que se ejecutan bajo su propia identidad de usuario local, pero no pueden depurar los procesos de otro usuario. Los administradores pueden depurar cualquier proceso. Para realizar la depuración en un servidor remoto, se necesita privilegios de administrador en el equipo donde se ejecuta el proceso que se va a depurar. Depuración de secuencias de comandos en el cliente Además de la depuración de aplicaciones en el servidor, Visual Debugger permite depurar secuencias de comandos de cliente escritas en ECMAScript (JavaScript) o en VBScript. La depuración de secuencias de comandos en el cliente puede ser especialmente útil cuando tiene controles de servidor Web que utilizan secuencias de comandos cliente. HABILITAR LA DEPURACIÓN EN ASP.NET Habilitar la depuración ASP.NET en las propiedades del proyecto (Visual Basic/C #) 1. 2. 3. En el Explorador de soluciones, Clic con el botón secundario del mouse en el nombre de un proyecto web y seleccionar Páginas de propiedades. Aparecerán las Páginas de propiedades de <proyecto>. Clic en la ficha Web. En Depuradores, activar la casilla ASP.NET. Habilitar la depuración en el archivo web.config 1. Abrir el archivo web.config utilizando cualquier editor de texto estándar o un analizador XML. a. Sin embargo, no se puede tener acceso al archivo en modo remoto utilizando un explorador web. Por motivos de seguridad, ASP.NET configura Microsoft IIS para impedir el acceso directo del explorador a los archivos Web.config. Si se intenta obtener acceso a un archivo de configuración utilizando un explorador, se obtendrá el error de acceso 403 de HTTP (prohibido). 2. Web.config es un archivo XML, por lo que contiene secciones anidadas marcadas por etiquetas. El siguiente ejemplo muestra un archivo Web.config típico. Modificar el archivo siguiendo estos pasos: a. Buscar la etiqueta <compilation>. Esta etiqueta marca el comienzo de la sección <compilation>. 81 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 b. 3. En la etiqueta <compilation>, crear el atributo de depuración. En el ejemplo siguiente, debug es el segundo atributo especificado en la etiqueta <compilation>, pero el orden no tiene importancia. c. Los atributos distinguen entre mayúsculas y minúsculas, por consiguiente, asegurarse de que especifica "debug", y no "Debug" ni "DEBUG". d. Establezca debug en true, como se muestra en el ejemplo de código siguiente. Si no se establece el atributo de depuración en true y se intenta iniciar una sesión de depuración, aparecerá un cuadro de diálogo para crear un archivo web.config conteniendo el atributo de depuración establecido. Aceptar y continuar para depurar. <configuration> <system.web> <compilation defaultLanguage="VB" debug="true" numRecompilesBeforeAppRestart="15"> <compilers> <compiler language="VB;VBScript" extension=".cls" type="Microsoft.VisualBasic.VBCodeProvider,system, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> < compiler language="C#;Csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider,system, PublicKeyToken=b77a5c561934e089" /> Version=1.0.5000.0, Culture=neutral, </compilers> <assemblies> "" <add assembly="ADODB" /> <add assembly="*" /> </assemblies> <namespaces> <add namespace="System.Web" /> <add namespace="System.Web.UI" /> <add namespace="System.Web.UI.WebControls" /> <add namespace="System.Web.UI.HtmlControls" /> 82 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 </namespaces> </compilation> </system.web> </configuration> 19 CONFIGURAR UN ENTORNO PARA REALIZAR LA DEPURACIÓN REMOTA Para habilitar la depuración remota, se puede: Instalar el Monitor de depuración remota (msvsmon.exe) en el equipo remoto e iniciarlo cuando se inicie la depuración, o Ejecutar el Monitor de depuración remota desde un recurso compartido de forma remota. Ejecutar el Monitor de depuración remota desde un recurso compartido de archivos es la forma más sencilla de habilitar la depuración remota. Visual Studio instala msvsmon.exe en estos directorios: Ruta de Ruta de Ruta de Los componentes acceso de instalación\Microsoft Visual Studio 8\Common7\IDE\Remote Debugger\x86 acceso de instalación\Microsoft Visual Studio 8\Common7\IDE\Remote Debugger\x64 acceso de instalación\Microsoft Visual Studio 8\Common7\IDE\Remote Debugger\ia64 IA 64 únicamente están disponibles en Visual Studio Team System. Al instalar Visual Studio en una plataforma de 64 bits, se instalan los componentes de depuración remota en plataformas de 64 bits y x86. Al instalar Visual Studio en una plataforma x86, se instalan de forma predeterminada componentes de depuración remota para x86; los componentes de depuración de 64 bits se instalan si se elige la opción adecuada durante la instalación. Al instalar el Monitor de depuración remota en una plataforma x86, únicamente se instalan los componentes de depuración remota de x86. No hay ninguna opción para instalar los componentes de 64 bits. Si se comparte el directorio del depurador remoto en el equipo que ejecuta Visual Studio, es posible ejecutar msvsmon.exe en el equipo remoto. Las características de depurador siguientes no funcionan cuando el Monitor de depuración remota se ejecuta desde un recurso compartido: Ejecutar paso a paso un servicio Web XML. (Aún es posible adjuntar de forma manual). Depurar automáticamente una aplicación web de ASP.NET. (Aún es posible adjuntar de forma manual). Como alternativa a la ejecución desde un recurso compartido, se puede usar el CD del depurador remoto de Visual Studio 2005 para instalar los componentes de depuración remota necesarios en el equipo remoto. Esta instalación proporciona acceso a todas las características de depuración remota. Al ejecutar el depurador remoto en una plataforma x86, únicamente se instalan los componentes de depuración remota de x86. No hay ninguna opción para instalar los componentes de 64 bits. Si se ejecuta en una plataforma de 64 bits, se instalan los componentes de 64 bits y x86. En algunos escenarios de depuración, es preciso instalar componentes adicionales. Para instalar los componentes de depuración remota 1. 2. 3. 4. El depurador remoto se encuentra en el último disco del juego de instalación de Visual Studio. Insertar este disco en el equipo remoto. Por ejemplo, si hay cuatro discos en el juego de instalación, insertar el cuarto disco en el equipo remoto. Si tiene un DVD en lugar de un CD, insertar el DVD. En el Explorador de Windows, abrir el CD o DVD. Buscar la carpeta Remote Debugger (en el CD) o vs/Remote Debugger (en el DVD). En la carpeta Depurador remoto, abrir la subcarpeta que coincide con su plataforma (x86, x64 o IA-64). Iniciar la copia de rdbgsetup.exe situada en esa subcarpeta y siga las instrucciones para finalizar la instalación. Se puede instalar los componentes de depuración remota copiando manualmente los archivos. Ver Componentes de depuración remota para obtener una lista de componentes necesarios y sus ubicaciones de instalación. Visual Studio incluye versiones independientes del Monitor de depuración remota para las plataformas de 32 bits y de 64 bits. Si utiliza rdbgsetup.exe, la 83 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 5. instalación de componentes remotos instalará automáticamente la versión correcta del Monitor de depuración remota. Si se copian manualmente los archivos, asegurarse de copiar la versión correcta. Una vez instalados los componentes de depuración remota, asegurarse que tiene los permisos necesarios para depurar un programa en el equipo remoto. Configurar el Firewall de Windows El Firewall de Windows se debe configurar para habilitar la depuración remota. Al iniciar por primera vez la depuración remota, Visual Studio realiza la configuración necesaria en el equipo host de Visual Studio. De igual manera, al ejecutar por primera vez el Monitor de depuración remota en un equipo remoto, el Monitor de depuración remota configura el Firewall de Windows en ese equipo. En Windows XP, esta configuración es completamente transparente y automática, pero en Windows Vista, el nuevo modelo de seguridad requiere la concesión de permiso antes de que el software pueda configurar el Firewall. Este permiso se concede a través del cuadro de diálogo Control de cuentas de usuario. Cuando el Monitor de depuración remota tiene que configurar el Firewall de Windows en el equipo remoto, el cuadro de diálogo Control de cuentas de usuario aparece en el equipo remoto. Si el equipo remoto no está visible, puede que no se haya dado cuenta de que el cuadro de diálogo Control de cuentas de usuario ya ha aparecido en su monitor. En ese caso, puede creer equivocadamente que la depuración remota ha dejado de responder. El Monitor de depuración remota está simplemente esperando que alguien conceda permiso en el cuadro de diálogo Control de cuentas de usuario del equipo remoto. Una manera de evitar este problema es configurar previamente el Firewall en el equipo remoto mediante el Asistente para configuración del depurador remoto. Para configurar el Firewall de Windows mediante el Asistente para configuración del depurador remoto 1. 2. 3. 4. Asegurarse de que los componentes de depuración remota se han instalado en el equipo. Inicio Todos los programas Visual Studio 9.0 Asistente para configuración del depurador remoto. Inicio Todos los programas Visual Studio 9.0 Depurador remoto. Seguir las instrucciones del Asistente para configuración del depurador remoto. Comenzar la depuración remota 1. Asegurarse de tener los permisos de depuración remota necesarios en el equipo remoto. 2. Para la depuración remota distinta de SQL, asegurarse de que está ejecutando el Monitor de depuración remota en el equipo remoto. Si se está depurando SQL, el Monitor de depuración remota se iniciará automáticamente durante la depuración. 3. Iniciar Visual Studio en el host del depurador. Utilizar Visual Studio para asociarse a un programa a desee depurar en el equipo remoto, o iniciar un programa a depurar en el equipo remoto. 20 DEPURAR LAS EXCEPCIONES SIN TRAZAR AL UTILIZAR ASP.NET AJAX: MÉTODOS SYS.DEBUG EN EL CLIENTE; CONEXIÓN DE UN PROGRAMA DE DEPURACIÓN A WINDOWS INTERNET EXPLORER Las aplicaciones ASP.NET habilitadas para AJAX contienen una mezcla de código de servidor y código de cliente. El explorador también puede solicitar datos adicionales de forma asincrónica. Esto puede convertir la depuración de aplicaciones web habilitadas para AJAX en un desafío. Escenarios 84 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Se puede utilizar los enfoques siguientes para depurar una aplicación ASP.NET habilitada para AJAX en las diferentes fases de desarrollo: Habilitar la depuración en el archivo de configuración. Utilizar trazas en el servidor. Utilizar los métodos de la clase Sys.Debug para establecer puntos de interrupción y administrar el resultado del seguimiento. Habilitar la depuración en el explorador. Asociar el depurador de Visual Studio 2008 a la instancia de Internet Explorer o utilizar herramientas externas para depurar en otros exploradores. Utilizar herramientas externas para capturar el tráfico HTTP. Información general La arquitectura de AJAX en ASP.NET ofrece un modelo para los modos de lanzamiento y depuración. El modo de lanzamiento permite la comprobación de errores y el control de excepciones optimizados para el rendimiento, con un tamaño de script mínimo. El modo de depuración dispone de características de depuración más sólidas, como la comprobación de tipos y argumentos. Si se crea versiones de depuración de archivos de script de cliente o recursos de script, ASP.NET ejecuta las versiones de depuración cuando la aplicación está en modo de depuración. Esto permite iniciar excepciones en los scripts de depuración, manteniendo un tamaño mínimo del código de lanzamiento. Una clase de aplicación auxiliar de depuración, Sys.Debug, proporciona métodos para mostrar los objetos con un formato legible al final de una página web. También muestra los mensajes de seguimiento de la traza, permite utilizar aserciones y permite irrumpir en el depurador. La API del objeto Error extendida proporciona información útil sobre las excepciones y admite los modos de lanzamiento y depuración. En las secciones siguientes se proporciona información detallada acerca de las técnicas y herramientas que puede utilizar para depuración y traza. Configurar la aplicación para depuración Para habilitar la depuración, agregar un elemento compilation al archivo raíz Web.config del sitio y, a continuación, establecer el atributo debug en true. En el ejemplo siguiente se muestra una sección de un archivo Web.config que tiene establecido el atributo debug para depuración. Copiar <configuration> <system.web> <compilation debug="true"> <!-- etc. --> </compilation> </system.web> <configuration> Cuando la depuración está habilitada, ASP.NET utiliza la versión de depuración de Microsoft AJAX Library y las versiones de depuración de los archivos de script de cliente personalizados, si están disponibles. Cambiar la aplicación del modo depuración al modo lanzamiento para su implementación Cuando se implemente una versión de lanzamiento de una aplicación ASP.NET habilitada para AJAX, establecer la aplicación en modo de lanzamiento. De esta manera, se asegura de que ASP.NET utiliza la versión de lanzamiento optimizada para el rendimiento de las bibliotecas de AJAX. Si se ha creado versiones de depuración y de lanzamiento de sus archivos de script personalizados y de los recursos del script, ASP.NET también utilizará las versiones de lanzamiento. Para establecer la aplicación en modo de lanzamiento: En el archivo Web.config, si el elemento compilation contiene un atributo debug, asegurarse de que el atributo debug está establecido en false. 85 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Asegurarse de que todas las páginas web que contienen un control ScriptManager tengan su propiedad ScriptMode establecida en Release. El atributo debug de la directiva @ Page no afecta a las aplicaciones de AJAX en ASP.NET. El control ScriptManager sólo utiliza los valores del archivo Web.config y de sus propiedades IsDebuggingEnabled y ScriptMode para determinar si debe representar los scripts de depuración. Trazas en el servidor Si se está utilizando trazas en el servidor para depurar las páginas web que tienen habilitada la representación parcial de la página, se debe utilizar el visor de seguimiento de trazas (Trace.axd) para mostrar el resultado de la traza. Se puede anexar el resultado de la traza al final de la página y se mostrará la primera vez que se represente la página. Sin embargo, la presentación de la traza no se actualiza como resultado de las devoluciones de datos asincrónicas, porque sólo cambia el contenido de los controles UpdatePanel que deban actualizarse. Nota: La representación parcial de la página está habilitada cuando la página contiene un control ScriptManager cuya propiedad EnablePartialRendering está establecida en true. La página también debe contener uno o varios controles UpdatePanel. Clase de aplicación auxiliar de depuración ASP.NET dispone de la clase Sys.Debug para depurar aplicaciones cliente. Mediante llamadas a los métodos de la clase Sys.Debug, puede mostrar los objetos en formato legible al final de la página, mostrar mensajes de seguimiento de la traza, utilizar aserciones e irrumpir en el depurador. Si se utiliza Visual Studio e Internet Explorer, se puede asociar el depurador de Visual Studio al explorador y ver los mensajes de seguimiento del depurador en la ventana Resultados. Si no utiliza Visual Studio, se puede ver los mensajes de seguimiento del depurador en Internet Explorer creando un elemento textarea en la página y estableciendo su id. en TraceConsole. En Mozilla Firefox, se puede ver los mensajes de traza del depurador mediante herramientas disponibles como extensiones. Los exploradores Apple Safari y Opera muestran los mensajes de traza en sus respectivas consolas de depuración. En la siguiente tabla se enumeran los métodos de la clase Sys.Debug. Sys.Debug.assert(condición, mensaje, mostrarLlamador) Comprueba una condición y, si ésta es false, muestra un mensaje y solicita al usuario que irrumpa en el depurador. Sys.Debug.clearTrace() Borra todos los mensajes de seguimiento de la traza del elemento TraceConsoletextarea. Sys.Debug.traceDump(objeto, nombre) Vuelca un objeto a la consola del depurador y al elemento TraceConsoletextarea, si está disponible. Sys.Debug.fail(mensaje) Muestra un mensaje en la ventana de resultados del depurador e irrumpe en el depurador. Sys.Debug.trace(texto) Anexa una línea de texto a la consola del depurador y al elemento TraceConsoletextarea, si está disponible. En el ejemplo siguiente se muestra cómo llamar a los métodos de la clase Sys.Debug: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"> <title>Untitled Page</title> 86 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 <script language="javascript" type="text/javascript"> function btnAssert_onclick() { var n; // Insert code intended to set n to a positive integer. if (false) n = 3; // Assert if n is not greater than 0. Sys.Debug.assert(n > 0, "n must be set to a positive integer."); } function btnFail_onclick() { var n; // Insert code intended to set n to a numeric value. if (false) n = 3; // Fail if n is not numeric. if (isNaN(n)) Sys.Debug.fail("The value of n must be a number."); } function btnTrace_onclick() { v = form1.text1.value; Sys.Debug.trace("Name set to " + "\"" + v + "\"."); alert("Hello " + v + "."); } function btnDump_onclick() { Sys.Debug.traceDump(form1.text1, "Name textbox"); alert("Hello " + form1.text1.value + "."); } function btnClear_onclick() { Sys.Debug.clearTrace() alert("Trace console cleared."); 87 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 } </script> </head> <body> <form id="form1" runat="server"> <h2>Sys.Debug Methods Test Page</h2> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <p><b>Use these buttons to demonstrate the assert() and fail() methods:</b><br /> <input id="btnAssert" type="button" value="Assert" style="width: 100px" onclick="return btnAssert_onclick()" /> &nbsp <input id="btnFail" type="button" value="Fail" style="width: 100px" onclick="return btnFail_onclick()" /> </p><hr /> <b>Use the textbox and buttons below to demonstrate tracing.</b> <br /> <p>Enter your name here:<br /> <input id="text1" maxlength="50" type="text" /> <br /> <br /> <input id="btnTrace" type="button" value="Trace" style="width: 100px" onclick="return btnTrace_onclick()" /><br /> <input id="btnDump" type="button" value="TraceDump" style="width: 100px" onclick="return btnDump_onclick()" /><br /> <input id="btnClear" type="button" value="ClearTrace" style="width: 100px" onclick="return btnClear_onclick()" /><br /> <br /></p> View output in the TraceConsole textarea below. <br /> 88 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 <textarea id='TraceConsole' rows="10" cols="50" title="TraceConsole"></textarea> </form> </body> </html> Configurar Internet Explorer para depuración De forma predeterminada, Internet Explorer pasa por alto los problemas que encuentra en JavaScript. Se puede habilitar la depuración utilizando el procedimiento siguiente. Para habilitar la depuración en Internet Explorer 1. 2. En el menú Herramientas, Clic en Opciones de Internet. En la ficha Opciones avanzadas, desactivar la casilla Deshabilitar la depuración de scripts (Internet Explorer) y la casilla Deshabilitar la depuración de scripts (otros). 3. Activar la casilla Mostrar una notificación sobre cada error de script. 4. Para desactivar los mensajes de error descriptivos, desactivar la casilla Mostrar mensajes de error HTTP descriptivos. Si los mensajes de error descriptivos están habilitados y una respuesta de error HTTP 500 del servidor tiene una longitud inferior a 513 bytes, Internet Explorer enmascara el contenido. En lugar de la información de error, Internet Explorer muestra un mensaje destinado a los usuarios finales, no a los programadores. Asociar el depurador de Visual Studio a Internet Explorer Para depurar el script de cliente, debe asociar un depurador a Internet Explorer. En Visual Studio, si inicia su aplicación para depuración (presionando F5 o utilizando el comando Iniciar depuración del menú Depurar ), el depurador se asocia automáticamente. También se puede asociar el depurador de Visual Studio a Internet Explorer cuando la aplicación ya se está ejecutando. Para ello, en el menú Depurar, Clic en Asociar al proceso En el cuadro de diálogo Asociar al proceso, seleccionar la instancia de Internet Explorer (iexplore.exe) a la se que desea asociar el depurador. Nota: Si Internet Explorer está configurado para depuración, la columna Tipo de la instancia pertinente de Internet Explorer muestra Script, x86. Si sólo ve x86 en la columna Tipo, asegurarse de que ese Internet Explorer está configurado para depuración. Si Internet Explorer encuentra un error de script y está configurado para la depuración de scripts, pero no está asociado a ningún depurador, el explorador solicita que seleccione un depurador. Se puede continuar sin depurar o asociar un depurador y ejecutar el código paso a paso. Problemas de depuración conocidos de Internet Explorer y soluciones alternativas Cuando se depuran aplicaciones de ASP.NET AJAX que utilizan Internet Explorer, tener en cuenta los problemas siguientes y las soluciones alternativas: Una vez asociado el depurador de Visual Studio a Internet Explorer, se puede ver una lista de los scripts que se están depurando en la ventana Explorador de scripts. (Para mostrar esta ventana, en el menú Depurar, clic en Ventanas y, a continuación, clic en Explorador de scripts.) La biblioteca de clientes de ASP.NET AJAX aparecerá como un recurso comenzando por ScriptResource.axd?..., que el servidor genera dinámicamente del ensamblado de ASP.NET AJAX. Un problema conocido de Visual Studio podría impedir abrir el archivo. Si Visual Studio muestra un mensaje de error a este respecto, o si pasa por alto los clics en el nombre del archivo, cierre todos los archivos de script que están abiertos. A continuación, abrir la página y seleccione los archivos de script que desea depurar. No puede establecer puntos de interrupción en código JavaScript dentro de los elementos script de una página ASP.NET hasta el depurador haya ejecutado paso a paso el código JavaScript de esa página. Para solucionar este problema, establecer el punto de interrupción en la función de la que proviene la llamada y ejecutar paso a paso el código de la página web ASP.NET. Después de que el depurador se haya detenido en una línea de código JavaScript de la página, se 89 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 puede establecer los puntos de interrupción como de costumbre. Otra manera de que el depurador reconozca los scripts de una página ASP.NET es crear un método en el archivo de paginación de ASP.NET que llame al método Sys.Debug.fail. Cuando se llama a este método, el depurador se detiene en la llamada a Sys.Debug.fail y permite establecer los puntos de interrupción en otra parte. Una tercera alternativa es colocar todo el código personalizado en archivos JavaScript externos. Visual Studio permite establecer puntos de interrupción en la primera línea de una función JavaScript normal, pero no en la primera línea de métodos anónimos, que ASP.NET utiliza en las bibliotecas de AJAX. Si un método anónimo contiene sólo una línea de código, o si debe establecer un punto de interrupción en la primera línea de un método anónimo, inserte una línea ficticia de código. A continuación, puede establecer el punto de interrupción en la segunda línea del método. Problemas conocidos de IIS 7.0 Cuando se ejecutan páginas ASP.NET habilitadas para AJAX mediante IIS 7.0 en Windows Vista, y el modo de canalización administrada está establecido en Integrada, los scripts procesados por la clase ScriptResourceHandler no se almacenan en la memoria caché. Sin embargo, los scripts se almacenan en la memoria caché cuando el modo de canalización administrada está establecido en Clásica. Capturar el tráfico HTTP Al desarrollar aplicaciones web, suele resultar útil supervisar el tráfico HTTP entre el servidor y el cliente. Una herramienta que puede realizar esta tarea es Fiddler, que se puede obtener en Fiddler PowerToy page, en el sitio web de MSDN. Fiddler se ejecuta como un proxy que registra todo el tráfico HTTP. Admite Internet Explorer y otros exploradores. Con Fiddler puede examinar cada solicitud y respuesta, incluidos encabezados, cookies y contenido del mensaje. Depuración en Mozilla Firefox Mozilla Firefox no se integra con el depurador de Visual Studio. Por consiguiente, no se puede utilizar el depurador de Visual Studio para ejecutar paso a paso el código de cliente que se está ejecutando en Firefox. Sin embargo, Firefox admite alguna funcionalidad de depuración, como una consola de JavaScript. También puede instalar las extensiones siguientes disponibles en Mozilla para mejorar sus funciones de depuración: FireBug permite a ejecutar paso a paso el script de cliente y examinar los elementos DOM de HTML. También proporciona una consola de scripts, una línea de comandos y otras herramientas. JavaScript Debugger (también conocido como "Venkman") ofrece un entorno de depuración de JavaScript que incluye un explorador de código fuente y otras características. Web Developer extension permite inspeccionar los estilos DOM y CSS. Fiddler también funciona con Firefox. Sin embargo, debe configurar Firefox para enrutar las solicitudes HTTP a través del proxy que se está ejecutando en el puerto 8888 del equipo local 21 IMPLEMENTAR EL SEGUIMIENTO DE UNA APLICACIÓN WEB: Trace.axd, Trace=True on @Page directive,<trace enabled="true"/> El seguimiento en ASP.NET permite ver información de diagnóstico acerca de una única solicitud para una página ASP.NET. El seguimiento de ASP.NET permite seguir la ruta de acceso de ejecución de una página, mostrar información de diagnóstico en tiempo de ejecución y depurar la aplicación. El seguimiento de ASP.NET se puede integrar en un seguimiento del nivel del sistema que proporciona varios niveles de resultados de seguimiento en aplicaciones distribuidas y de varios niveles. Características La traza de ASP.NET ofrece las siguientes características: Debugging statements Se puede escribir instrucciones de depuración en el código, sin necesidad de quitarlas de la aplicación cuando se implemente en los servidores de producción. También se puede escribir variables o estructuras en una página y seguir la traza de la ruta de ejecución de la página o de la aplicación. Integrated tracing functionality Se puede enrutar mensajes emitidos por la clase System.Diagnostics.Trace al resultado de traza de ASP.NET y enrutar mensajes emitidos por la traza de ASP.NET a System.Diagnostics.Trace. También se puede reenviar los eventos de instrumentación de ASP.NET a System.Diagnostics.Trace. Programmatic access to trace messages Se puede tener acceso y manipular mensajes de traza a partir del código para un control más preciso del formato de los mensajes de traza o para el procesamiento adicional requerido. 90 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Application-level tracing La opción de traza del nivel de aplicación permite ver los datos de traza más recientes disponibles sin necesidad de reiniciar una sesión de traza ni de aumentar el volumen de datos de traza que debe almacenar el servidor. Se muestran los datos más recientes de traza y se descartan los más antiguos. Background El seguimiento de traza anexa la información de diagnóstico y los mensajes de traza personalizados al resultado de la página y envían esta información al explorador que realizó la solicitud. Opcionalmente, se puede ver esta información en otro visor de traza (Trace.axd), que muestra los datos de traza de todas las páginas de la aplicación web ASP.NET. La información de traza puede ayudarle a investigar errores o resultados no deseados mientras ASP.NET procesa una solicitud de página. Se puede configurar páginas individuales para mostrar información de seguimiento. De forma alternativa, se puede configurar el archivo Web.config de la aplicación para que todas las páginas muestren información de seguimiento a menos que la página deshabilite explícitamente el seguimiento. El establecimiento de la traza en el nivel de aplicación es útil ya que no necesita realizar cambios en las páginas individuales para habilitarla y deshabilitarla. Las instrucciones de seguimiento sólo se procesan y se muestran cuando el seguimiento está habilitado. Es posible controlar si el seguimiento se muestra en la página, en el visor de seguimiento o en ambos. Traza de ASP.NET en la aplicación La traza en el nivel de aplicación se habilita mediante el elemento trace del archivo Web.config. Cuando se habilita el seguimiento del nivel de aplicación, ASP.NET recopila la información de seguimiento de cada solicitud realizada a la aplicación, hasta llegar al número máximo de solicitudes especificado. El número predeterminado de solicitudes es 10. De forma predeterminada, cuando el visor de seguimiento alcanza este límite, la aplicación deja de almacenar solicitudes de seguimiento. Se puede configurar la traza para almacenar los datos de seguimiento más antiguos (descartando elementos más recientes) o la información de traza más reciente (descartado elementos más antiguos). Nota: Cuando se habilita la traza para toda la aplicación en el archivo Web.config, la información se recopila y procesa para cada página de la aplicación. Para reemplazar la configuración de la aplicación, se establece el atributo Trace en la directiva @ Page de esa página en false. Las instrucciones Write o Warn que incluya en el código de una página se almacenan y envían únicamente al visor de seguimiento. Ver información de seguimiento Se puede ver la información de traza en la parte inferior de páginas individuales. También se puede utilizar el visor de traza (Trace.axd) para ver información de traza que ASP.NET recopila y almacena en caché cuando la traza está habilitada. Si se desea que la información de seguimiento aparezca al final de la página que está asociada a ella, se puede establecer el atributo PageOutput del elemento trace en true. Si se habilita la traza en el nivel de aplicación pero no se desea que se muestre información de traza de algunas páginas, se puede establecer el atributo Trace de la directiva @ Page de esas páginas en false. De forma predeterminada, el seguimiento de nivel de aplicación se puede ver sólo en el equipo local del servidor Web. Para hacer que la información de seguimiento del nivel de aplicación sea visible desde equipos remotos, puede establecer el atributo LocalOnly del elemento trace en false. Nota: Para ayudar a proteger la aplicación web, se utiliza la capacidad de traza remota únicamente cuando se programa o se instala la aplicación. Asegurarse de que se deshabilita antes de transferir la aplicación a los servidores web de producción. Para ello, se establece el atributo LocalOnly en true en el archivo Web.config. El ejemplo siguiente muestra una configuración de traza de aplicación que recoge información de traza para un máximo de 40 solicitudes. También habilita exploradores en equipos distintos del servidor para mostrar el visor de traza. <configuration> <system.web> <trace enabled="true" requestLimit="40" localOnly="false" /> </system.web> 91 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 </configuration> Escribir mensajes de seguimiento de ASP.NET personalizados Se puede anexar la información de traza personalizada a la presentación de traza de una página ASP.NET o al registro de traza. La información de traza que se escribe en el registro de traza se puede ver con el visor de traza. Puede escribir información de traza mediante los métodos Warn o Write de la clase TraceContext. La diferencia entre los dos métodos es que un mensaje escrito con el método Warn aparece con el texto en rojo. El ejemplo de código siguiente muestra cómo usar la clase TraceContext para mostrar información de traza al final de una página ASP.NET. Se inicia una excepción diferente para cada control LinkButton que produjo la devolución de datos. El mensaje de error que se usa para inicializar las instancias ArgumentException o InvalidOperationException se muestra en el registro de traza. <%@ Page Language="C#" Trace="true" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server"> void Page_Load(object sender, EventArgs e) { try { if (IsPostBack) { switch (Request.Form[" EVENTTARGET"]) { case "WarnLink": throw new ArgumentException("Trace warn."); break; case "WriteLink": throw new InvalidOperationException("Trace write."); break; default: throw new ArgumentException("General exception."); break; } } } catch (ArgumentException ae) { 92 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Trace.Warn("Exception Handling", "Warning: Page_Load.", ae); } catch (InvalidOperationException ioe) { Trace.Write("Exception Handling", "Exception: Page_Load.", ioe); } } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Trace Example</title> </head> <body> <form id="form1" runat="server"> <div> <asp:LinkButton id="WriteLink" runat="server" text="Generate Trace Write" /> <asp:LinkButton id="WarnLink" runat="server" text="Generate Trace Warn" /> </div> </form> </body> </html> Leer la información de seguimiento de ASP.NET Se puede ver la información de traza que se anexa al final de una página ASP.NET o en el visor de traza. En ambos casos, la información mostrada es la misma. ASP.NET organiza la información de traza en una serie de tablas. La información de seguimiento aparece en el orden siguiente. 93 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 La sección Detalles de la solicitud muestra información general sobre la solicitud actual y la respuesta. Valor Descripción Id. de sesión Identificación de sesión de la solicitud especificada. Hora de la solicitud Hora en que se efectuó la solicitud. Codificación de la solicitud Codificación de caracteres de la solicitud. Tipo de solicitud Método HTTP (GET o POST). Código de estado Valor de código de estado asociado a la respuesta. Codificación de respuesta Codificación de caracteres para la respuesta. Información de seguimiento La sección Información de seguimiento muestra el flujo de eventos del nivel de página. Si se ha creado mensajes de seguimiento personalizados, los mensajes también se muestran en la sección Información de seguimiento. Valor Descripción Category Categoría de seguimiento personalizada especificada en una llamada al método Warn u Write, si la hay. Message Mensaje de seguimiento personalizado especificado en una llamada al método Warn u Write, si lo hay. Desde los Tiempo transcurrido en segundos desde que se procesó el primer mensaje de seguimiento. El primer mensaje de primeros seguimiento aparece en la parte superior de la lista. Desde los Tiempo transcurrido en segundos entre el procesamiento del mensaje de traza actual y el mensaje de traza últimos anterior. Árbol de control La sección Árbol de control muestra información sobre los controles de servidor ASP.NET que se crean en la página. Valor Descripción Id. de control Identificación del control. Si no ha especificado una propiedad ID para el control, ASP.NET genera ID mediante la propiedad UniqueID. Type Nombre de tipo completo del control. Bytes de tamaño del la Tamaño del control representado en bytes (incluidos los controles secundarios). Se trata del tamaño representación del contenido HTML, XML, etc., real que se envía al explorador. Tamaño en bytes de Tamaño en bytes del estado de vista del control (excluidos los controles secundarios). en bytes de Tamaño en bytes del estado de control del control (excluidos los controles secundarios). ViewState Tamaño ControlState Estado de sesión La sección Estado de sesión muestra información sobre los valores que se almacenan en el estado de sesión, si la hay. 94 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Valor Descripción Clave de sesión Clave para datos almacenados en el estado de sesión, si la hay. Type Tipo completo del objeto que almacena los datos. Valor Representación de cadena de los datos almacenados en el estado de sesión, si la hay. Estado de aplicación La sección Estado de la aplicación muestra información sobre los valores almacenados en el estado de la aplicación, si la hay. Valor Descripción Clave de aplicación Clave para datos almacenados en el estado de aplicación, si la hay. Type Tipo completo del objeto que almacena los datos. Valor Representación de cadena de los datos que se almacenan en el estado de aplicación, si la hay. Colección Cookies Las secciones Cookies de solicitud y Cookies de respuesta muestran información sobre las cookies que se pasan entre el explorador y el servidor en cada solicitud y respuesta. La sección muestra cookies permanentes y de la sesión. ASP.NET crea automáticamente algunas cookies, como las del estado de sesión basada en cookies y las de autenticación de formularios. Valor Descripción Nombre Nombre de la cookie. Valor Valor de la cookie o de las subclaves y valores, en caso de que la cookie tenga valores múltiples. Size Tamaño de la cookie en bytes. Colección Headers La sección Colección de encabezados muestra información sobre los pares nombre/valor de los encabezados de los mensajes de solicitud y respuesta, que proporcionan información sobre el cuerpo del mensaje o el recurso solicitado. La información de encabezado se utiliza para controlar cómo se procesan los mensajes de solicitud y cómo se crean los mensajes de respuesta. Valor Descripción Nombre Nombre del encabezado. Valor Valor del encabezado. Colección Form La sección Colección de formularios muestra pares de nombre/valor que indican los valores de elementos de formulario (valores de control) que se envían en una solicitud durante una operación POST (devolución de datos). Valor Descripción Nombre Nombre de la variable de formulario. Valor Valor de la variable de formulario. 95 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Colección de cadenas de consulta La sección Colección de cadenas de consulta muestra los valores que se pasan a la dirección URL. En una dirección URL, la información de la cadena de consulta se separa de la información de la ruta de acceso mediante un signo de interrogación (?); los elementos múltiples de la cadena de consulta se separan mediante un signo de Y comercial (&). Los pares de nombre/valor de la cadena de consulta se separan mediante un signo igual (=). La propiedad QueryString del objeto HttpRequest devuelve NameValueCollection de variables de la cadena de consulta. Valor Descripción Nombre Nombre de la variable de la cadena de consulta. Valor Valor de la variable de la cadena de consulta. Variables de servidor La sección Variables de servidor muestra una colección de variables de entorno relacionadas con el servidor e información del encabezado de la solicitud. La propiedad ServerVariables del objeto HttpRequest devuelve NameValueCollection de variables del servidor. Valor Descripción Nombre Nombre de la variable de servidor. Valor Valor de la variable de servidor. Seguimiento en ASP.NET y seguimiento de diagnósticos El seguimiento en ASP.NET escribe mensajes que se muestran en las páginas Web ASP.NET y el visor de seguimiento de ASP.NET (Trace.axd). En cambio, la clase System.Diagnostics.Trace se utiliza para seguir la traza de los mensajes de escritura en el resultado de traza de .NET Framework estándar (normalmente una ventana de consola). Para facilitar el seguimiento de la interacción entre las páginas web ASP.NET y los objetos de negocios y otros componentes, se puede integrar el resultado de traza de ASP.NET con la traza de System.Diagnostics. A continuación se puede enrutar todos los mensajes de traza a una de estas salidas. Un escenario común que usa tanto la traza en ASP.NET como System.Diagnostics.Trace son las páginas web que utilizan objetos de negocios de nivel intermedio para interactuar con datos y reglas de negocios. También puede usar System.Diagnostics.Trace en las páginas que usan servicios de la empresa como transacciones y colas. En estas situaciones, los componentes de empresa y negocio representan papeles clave en la ejecución correcta de la página. Además, puede ayudar con el análisis de la aplicación a supervisar el flujo de ejecución entre los diferentes niveles mediante un resultado de traza único. Atributos de configuración del seguimiento La tabla siguiente muestra los atributos que puede utilizar para modificar el comportamiento de la traza en el nivel de aplicación en el elemento trace del archivo Web.config. Atributo Descripción Enabled true para habilitar el seguimiento para a aplicación; de lo contrario, false. De manera predeterminada, es false. Se puede reemplazar esta configuración para las páginas individuales si establece el atributo Trace de la directiva @ Page de una página en true o false. PageOutput true para mostrar el seguimiento tanto en páginas como en el visor de seguimiento (Trace.axd); de lo contrario, false. De manera predeterminada, es false. RequestLimit Número de solicitudes de seguimiento que se almacenan en el servidor. El valor predeterminado es 10. TraceMode Orden en que se muestra la información de seguimiento. Se establece en SortByTime para ordenar en el orden en el que se procesó la información. Establecer en SortByCategory para ordenar alfabéticamente por categorías definidas 96 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 por el usuario. De manera predeterminada, es SortByTime. LocalOnly true para hacer que el visor de seguimiento (Trace.axd) esté disponible sólo para el servidor Web de host; de lo contrario, false. De manera predeterminada, es true. MostRecent true para mostrar la información de traza más reciente como resultado de traza; de lo contrario, false. Si este valor es false, cuando se supera el valor de requestLimit, las nuevas solicitudes no se almacenan. De manera predeterminada, es false. Referencia de clase Clase Descripción System.Diagnostics.Trace La clase principal para implementar la traza. TraceContext Captura y muestra los detalles de ejecución acerca de una solicitud Web. 22 DEPURAR LOS PROBLEMAS DE IMPLEMENTACIÓN: ASPNET_REGIIS.EXE; CREACIÓN DE UNA APLICACIÓN WEB IIS; CONFIGURACIÓN DE LA VERSIÓN DE .NET FRAMEWORK Cuando se ejecutan varias versiones de .NET Framework simultáneamente en un único equipo, la versión de las API de servidor de Internet (ISAPI) de ASP.NET asignada a una aplicación ASP.NET determina qué versión de Common Language Runtime (CLR) se utiliza para la aplicación. La herramienta Registro de IIS en ASP.NET (Aspnet_regiis.exe) permite que un programa administrador o de instalación pueda actualizar fácilmente las asignaciones de secuencias de comandos de una aplicación ASP.NET para que señalen la versión de ISAPI (API de servidor de Internet) de ASP.NET asociada a la herramienta. Esta herramienta también se puede utilizar para mostrar el estado de todas las versiones de ASP. NET instaladas, para registrar la versión de ASP.NET que se corresponde con la herramienta, para crear directorios de secuencias de comandos de cliente y para realizar otras operaciones de configuración. Nota: .NET Framework incluye dos herramientas de registro de IIS: una para los sistemas estándar y otra para los sistemas de 64 bits. La herramienta para los sistemas de 64 bits está ubicada en el directorio Framework64 del directorio Microsoft.NET dentro de la carpeta Windows; por ejemplo, C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727 contiene la herramienta Registro de IIS. aspnet_regiis [opciones] Opción Descripción -c Instala las secuencias de comandos de cliente para ASP.NET en el subdirectorio aspnet_client de cada uno de los directorios de Internet Information Services (IIS), por ejemplo, secuencias de comandos de validación del cliente. Sólo se instalan las secuencias de comandos del cliente de la versión de ASP.NET asociada a Aspnet_regiis.exe. -disable Deshabilita ASP.NET en la consola de seguridad de IIS. Esta opción sólo se puede combinar con las opciones -i, -ir o -r. No está disponible con las versiones de IIS anteriores a la IIS 6.0. -e Quita las secuencias de comandos del cliente para ASP.NET del subdirectorio aspnet_client de cada uno de los directorios de sitio IIS. Sólo se quitan las secuencias de comandos del cliente de la versión de ASP.NET asociada a Aspnet_regiis.exe. -ea Quita las secuencias de comandos del cliente de todas las versiones de ASP.NET del subdirectorio aspnet_client de cada uno de los directorios de sitio IIS. -enable Habilita ASP.NET en la consola de seguridad de IIS. Esta opción sólo se puede combinar con las opciones -i, -ir o -r. No está disponible con las versiones de IIS anteriores a IIS 6.0 o con versiones de ASP.NET anteriores a la versión 2.0 de ASP.NET. -ga user Concede al usuario o grupo especificado acceso a la metabase de IIS y a otros directorios utilizados por ASP.NET. Esta opción no está disponible en las versiones de ASP.NET anteriores a la versión 2.0 de ASP.NET. -i Instala la versión de ASP.NET asociada a Aspnet_regiis.exe y actualiza las asignaciones de secuencias de comandos ubicadas en la raíz de la metabase de IIS y por debajo de ésta. Sólo se actualizan las asignaciones de secuencias de 97 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 comandos de las aplicaciones que utilizan una versión anterior de ASP.NET. Las aplicaciones que utilizan una versión posterior no se ven afectadas. -ir Instala la versión de ASP.NET asociada a Aspnet_regiis.exe y sólo registra ASP.NET en IIS. Esta opción no actualiza las asignaciones de secuencias de comandos. Para instalar ASP.NET y actualizar dichas asignaciones, utilice la opción -i. -k path Quita las asignaciones de secuencias de comandos (de todas las versiones de ASP.NET) de todas las aplicaciones ASP.NET ubicadas en la ruta de acceso raíz de la aplicación especificada y en los subdirectorios de la misma. -kn path Quita las asignaciones de secuencias de comandos (de todas las versiones de ASP.NET) solamente de la aplicación ASP.NET ubicada en la ruta de acceso raíz de la aplicación especificada. Esta opción no afecta a las aplicaciones de los subdirectorios de la path especificada. -lk Enumera la ruta de acceso y la versión de todas las claves de metabase de IIS asignadas a ASP.NET. No se muestran las claves que heredan asignaciones de secuencias de comandos de ASP.NET de una clave primaria. -lv Enumera el estado y la ruta de instalación de todas las versiones de ASP.NET instaladas en el equipo. - Impide el reinicio del Servicio de publicación en World Wide Web después de instalar o actualizar mapas de la secuencia norestart de comandos de ASP.NET. Si no utiliza esta opción, se reciclan todos los grupos de aplicaciones. Utilizar esta opción con las opciones -i o -r cuando se reinicie manualmente el proceso de trabajo de IIS. -r Actualiza todas las asignaciones de secuencias de comandos ubicadas en la metabase de IIS y por debajo de ésta para que señalen la versión de la ISAPI de ASP.NET asociada a Aspnet_regiis.exe. Todas las asignaciones de secuencias existentes se actualizan para señalar la versión ISAPI de ASP.NET asociada con la herramienta de registro IIS de ASP.NET, independientemente de la versión actual. -s path Instala la asignación de secuencias de comandos que señala la versión de la ISAPI de ASP.NET asociada a Aspnet_regiis.exe en todas las aplicaciones ASP.NET ubicadas en la ruta de acceso raíz especificada de la aplicación y en sus subdirectorios. Se actualizan todas las asignaciones de secuencias de comandos de la ruta de acceso especificada y por debajo de ésta que utilicen una versión anterior de la ISAPI de ASP.NET. -sn path Instala la asignación de secuencias de comandos que señala la versión de la ISAPI de ASP.NET asociada a la herramienta de la aplicación ASP.NET que se encuentra en la ruta de acceso raíz especificada de la aplicación. Se actualizan todas las asignaciones de secuencias de comandos de la ruta de acceso especificada que utilicen una versión anterior de la ISAPI de ASP.NET. Esta opción no afecta a las aplicaciones de los subdirectorios de path. -u Desinstala la versión de ASP.NET que está asociada con la herramienta de registro IIS de ASP .NET del equipo. Las asignaciones de secuencias de comandos de esta versión de la ISAPI de ASP.NET vuelven a asignarse automáticamente a la versión más reciente de la ISAPI de ASP.NET instalada. -ua Desinstala todas las versiones de ASP.NET del equipo. -? Muestra la sintaxis de comandos y las opciones de la herramienta de registro IIS de ASP.NET. OPCIONES DE CONFIGURACIÓN Opción Descripción -config+ Permite el acceso remoto a la configuración de ASP.NET en el equipo. -config- Deshabilita el acceso remoto a la configuración de ASP.NET en el equipo. -pa cuenta del contenedor Concede a la account del usuario o grupo especificado permiso para tener acceso al container de clave especificado. Este argumento acepta los modificadores opcionales siguientes: -pku Sustituye un contenedor especificado por el usuario por el contenedor de equipo predeterminado. - csp provider Especifica el proveedor de contenedores que se va a utilizar. -full Especifica que se debería agregar acceso total, en lugar del acceso de sólo lectura predeterminado. 98 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 -pc contenedor Crea un par de claves RSA públicas/privadas en el contenedor especificado. Este argumento acepta los modificadores opcionales siguientes: -size keySize Especifica el tamaño de la clave. El valor predeterminado son 1024 bytes. –pku Sustituye un contenedor especificado por el usuario por el contenedor de claves predeterminado en el equipo. –exp Especifica las claves privadas que deben poder exportarse. -csp provider Especifica el proveedor de contenedores que se va a utilizar. -pd sección Descifra la sección de configuración. Este argumento acepta los parámetros opcionales siguientes: app virtualPath Especifica que el descifrado debería producirse en el nivel de la ruta de acceso incluida. -location subPath Especifica el subdirectorio para descifrar. -pkm Especifica que debería descifrarse el archivo Machine.config en lugar del archivo Web.config. -pdf sección Descifra la sección de configuración especificada del archivo Web.config en el directorio físico (no webApplicationDirectory virtual) especificado. -pe sección Cifra la sección de configuración especificada. Este argumento acepta los modificadores opcionales siguientes: -prov provider Especifica el proveedor de cifrado que se va a utilizar. - app virtualPath Especifica que el cifrado debería producirse en el nivel de la ruta de acceso incluida. location subPath Especifica el subdirectorio para cifrar. -pkm Especifica que debería cifrarse el archivo Machine.config en lugar del archivo Web.config. -pef section Cifra la sección de configuración especificada del archivo Web.config en el directorio físico (no virtual) webApplicationDirectory especificado. -pi archivo contenedor Importa un par de claves RSA públicas/privadas al container especificado desde el file XML especificado. Este argumento acepta los modificadores opcionales siguientes: -pku Sustituye un contenedor especificado por el usuario por el contenedor de equipo predeterminado. -exp Especifica que se pueden exportar claves privadas. -csp provider Especifica el proveedor de contenedores que se va a utilizar. -pr cuenta del contenedor Quita el permiso para la account del usuario o grupo especificado para tener acceso al container de clave especificado. Este argumento acepta los modificadores opcionales siguientes: -pku Sustituye un contenedor especificado por el usuario por el contenedor de equipo predeterminado. - csp provider Especifica el proveedor de contenedores que se va a utilizar. -px archivo contenedor Exporta un par de claves RSA públicas/privadas del contenedor especificado al archivo XML especificado. Este argumento acepta los modificadores opcionales siguientes: -pku Sustituye un contenedor especificado por el usuario por el contenedor de equipo predeterminado. - csp provider Especifica el proveedor de contenedores que se va a utilizar. -pz contenedor Elimina el contenedor de claves especificado. Este argumento acepta el modificador opcional siguiente:pku Sustituye un contenedor especificado por el usuario por el contenedor de equipo predeterminado 23 SUPERVISAR APLICACIONES WEB: SUPERVISIÓN DE LA SALUD UTILIZANDO WEBEVENT, CONTADORES DE RENDIMIENTO La supervisión de estado de ASP.NET proporciona una manera fácil de supervisar el estado de una aplicación ASP.NET y de obtener información detallada en tiempo de ejecución sobre los recursos de ASP.NET (para instrumentar la aplicación). La supervisión de estado contiene clases de eventos de supervisión de estado web (eventos web) y proveedores de supervisión de estado (agentes de escucha) listos para usar. Los eventos web empaquetan información de eventos de estado. Los proveedores realizan escuchas en los eventos y consumen la información de evento, normalmente mediante el registro de la información o su notificación a un administrador. Puede conectar un evento web a un proveedor (lo que se denomina habilitar el evento) si establece la configuración en el archivo de configuración de la aplicación. El sistema de supervisión System.Web.Management. de estado de ASP.NET se implementa mediante clases en el espacio de nombres 99 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Configurar la supervisión de estado en ASP.NET Se puede configurar las aplicaciones para que usen proveedores de supervisión integrados o personalizados que procesen esta información de supervisión de estado e informen sobre el estado y las características de rendimiento de la aplicación instrumentada. Los proveedores y eventos web se agregan a una aplicación mediante la configuración de la sección healthMonitoring del archivo de configuración. A continuación usa clases integradas o personalizadas para realizar escuchas de los datos de evento y procesarlos. Jerarquía de clases de eventos web Cuando se provoca un evento Web, se crea una instancia de la clase de evento asociada. Los datos del evento se recogen en las propiedades de este objeto. Los proveedores de eventos procesan estos datos. Los eventos Web pueden contener información sobre el proceso de trabajo, el dominio de aplicación, los datos de solicitud, los datos de respuesta, los errores de aplicación y de configuración, así como los eventos de auditoría. Todas las clases de evento secundarias heredan la información de estado de una clase de evento primaria. En la siguiente ilustración se muestran las relaciones entre las clases de eventos web. Jerarquía de clases de eventos Web Jerarquía de clases de proveedores ASP.NET incluye proveedores integrados que se pueden utilizar para procesar los eventos Web. También se puede heredar de las clases integradas para crear un proveedor personalizado, sujeto a las siguientes limitaciones de herencia: Las aplicaciones que se ejecutan con cualquier nivel de confianza pueden heredar la clase WebEventProvider. 100 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Las aplicaciones que se ejecutan con cualquier nivel de confianza pueden heredar la clase BufferedWebEventProvider. Sólo las aplicaciones que se ejecutan con plena confianza pueden heredar la clase SqlWebEventProvider. Las demás clases no las pueden heredar las aplicaciones, independientemente del nivel de confianza. La siguiente ilustración muestra la relación entre las clases de proveedor web del espacio de nombres System.Web.Management. USAR LOS EVENTOS DE SUPERVISIÓN DE ESTADO DE ASP.NET Se Puede trabajar con los eventos de supervisión de estado de ASP.NET de las maneras siguientes: Utilizar clases de proveedor y de evento Web integradas. Normalmente, no será necesario proporcionar implementaciones personalizadas de las clases de evento web de ASP.NET. Tener en cuenta que la aplicación no provoca estos eventos sino que lo hace .NET Framework. Crear clases personalizadas para eventos web o proveedores. Los eventos web personalizados normalmente se crean cuando se debe anexar información personalizada a la que ya proporcionan los eventos web integrados. Los proveedores personalizados se crean normalmente si se desea entregar los datos de eventos a través de un mecanismo distinto del que proporcionan los proveedores integrados. UTILIZAR EVENTOS WEB Y PROVEEDORES INTEGRADOS El uso de eventos web integrados y proveedores para la supervisión de estado es la estrategia más común. Sólo se requiere configurar la aplicación para usar los eventos y proveedores necesarios. Se debe hacer lo siguiente: Agregar la clase de evento web integrada de ASP.NET que necesita al elemento eventMappings de la sección healthMonitoring en el archivo de configuración de la aplicación. Agregar el proveedor que utilice el evento al elemento providers de la sección healthMonitoring. Agregar un elemento al elemento rules que define la asociación entre el evento y el proveedor. De forma predeterminada, las clases de supervisión de estado integradas de ASP.NET se configuran en la sección healthMonitoring del archivo Web.config de la raíz. En la sección healthMonitoring se establece la siguiente configuración predeterminada: Todas las clases de evento Web que se deriven de WebBaseEvent se especifican en el elemento eventMappings. Esta sección se utiliza para asignar un nombre descriptivo a un grupo de clases de evento. Todas las clases de evento que derivan de WebBaseEvent se incluyen al menos en uno de los grupos definidos en el elemento eventMappings. 101 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Los proveedores de eventos EventLogWebEventProvider, WmiWebEventProvider y SqlWebEventProvider se especifican en el elemento providers. Se puede especificar otros proveedores integrados en el elemento providers, como las clases SimpleMailWebEventProvider, TemplatedMailWebEventProvider o TraceWebEventProvider. Las reglas que asocian el error Web y los eventos de error de auditoría a las clases EventLogWebEventProvider se especifican en el elemento rules. Se puede habilitar otros eventos web y proveedores si agrega más elementos rules. Un evento se considera habilitado si está asignado a un proveedor de eventos en el elemento rules. Debe configurar los elementos eventMappings y providers para el evento pero, a menos que ambos estén conectados en el elemento rules, el evento no estará habilitado. Se pueden especificar los valores de parámetro de los elementos configurados. Entre los ejemplos se incluyen parámetros que limitan el número de eventos que se pueden producir, que especifican el intervalo entre dos eventos o que especifican las opciones de almacenamiento en búfer de los eventos para los proveedores de correo y SQL. 24 IMPLEMENTAR FORMULARIOS WEB UTILIZANDO ASP.NET AJAX: EnablePartialRendering, ChildrenAsTriggers, Scripts, Services, UpdateProgress, Timer, ScriptManagerProxy Triggers, El control ScriptManager administra el script de cliente de las páginas web ASP.NET habilitadas para AJAX. De forma predeterminada, el control ScriptManager registra el script de Microsoft AJAX Library con la página. Esto permite al script de cliente usar las extensiones del sistema de tipos y admitir características como la representación parcial de páginas y las llamadas a servicios web. Escenarios Se debe usar un control ScriptManager en una página para habilitar las siguientes características AJAX de ASP.NET: Funcionalidad del script de cliente de Microsoft AJAX Library y cualquier script personalizado que desee enviar al explorador. Representación parcial de páginas, que permite actualizar de forma independiente regiones de la página sin una devolución de datos. Los controles ASP.NET UpdatePanel, UpdateProgress y Timer requieren un control ScriptManager para admitir la representación parcial de página. Clases de proxy de JavaScript para servicios web, que permiten usar script de cliente para tener acceso a servicios web y, en especial, a métodos marcados en páginas ASP.NET. Esto se consigue mediante la exposición de los servicios web y los métodos de página como objetos con establecimiento inflexible de tipos. Clases JavaScript para tener acceso a los servicios de aplicación de autenticación, perfil y funciones de ASP.NET. Información general Si una página contiene uno o varios controles UpdatePanel, el control ScriptManager administra la representación parcial de la página en el explorador. El control interactúa con el ciclo de vida de la página para actualizar las partes de la página que están dentro de los controles UpdatePanel. La propiedad EnablePartialRendering del control ScriptManager determina si una página participa en actualizaciones parciales de la página. De forma predeterminada, la propiedad EnablePartialRendering es true. Por tanto, la representación parcial de página está habilitada de forma predeterminada al agregar un control ScriptManager a la página. Administrar errores de representación parcial de páginas Durante la representación parcial de páginas, se puede administrar los errores de la manera siguiente: Establecer la propiedad AllowCustomErrorsRedirect. De esta forma determina cómo se usa la sección de errores personalizada del archivo Web.config cuando se produce un error durante una devolución de datos asincrónica. Administrar el evento AsyncPostBackError del control ScriptManager, que se provoca cuando hay un error de página durante una devolución de datos asincrónica. Establecer la propiedad AsyncPostBackErrorMessage, que es el mensaje de error que se envía al explorador. Usar las extensiones del sistema de tipos Microsoft AJAX Library agrega extensiones del sistema de tipos, que proporcionan espacios de nombres, herencia, interfaces, enumeraciones, reflexión y funciones auxiliares para las cadenas y matrices, a JavaScript. Estas extensiones proporcionan funcionalidad en el script de cliente similar a la de .NET Framework. Permiten escribir aplicaciones ASP.NET habilitadas para AJAX de una manera estructurada que mejora el mantenimiento, facilita la incorporación de características y facilita la funcionalidad de 102 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 capas. Al agregar un control ScriptManager a una página web ASP.NET se incluyen automáticamente las extensiones del sistema de tipos, de forma que puede usar la biblioteca en el script de cliente. Registrar script personalizado Usar el control ScriptManager para administrar recursos que se han creado para los controles que participan en actualizaciones parciales de la página. Los recursos incluyen scripts, estilos, campos ocultos y matrices. La colección Scripts del control ScriptManager contiene un objeto ScriptReference por cada script disponible en el explorador. Se puede especificar los scripts mediante declaración o mediante programación. El control ScriptManager también expone métodos de registro que puede usar para administrar script de cliente y campos ocultos mediante programación. Si se registra script o campos ocultos que admiten las actualizaciones parciales de página, se debe llamar a los métodos de registro del control ScriptManager. (Para registrar scripts que no se necesitan en las actualizaciones parciales de página, se usan métodos de la clase ClientScriptManager.) Nota: Los scripts de la página que se registran con el control ScriptManager y todo el script de control de eventos deben estar dentro del elemento form de la página. De lo contrario el script no se registrará ni ejecutará. Registrar servicios web Para registrar un servicio web que se desea llamar desde una página ASP.NET habilitada para AJAX, se agrega a la colección Services del control ScriptManager para registrarlo. El marco de trabajo de ASP.NET AJAX genera un objeto proxy de cliente para cada objeto ServiceReference de la colección Services. Las clases de proxy y sus miembros con establecimiento inflexible de tipos simplifican el uso de servicios web desde el script de cliente. Se puede agregar mediante programación los objetos ServiceReference a la colección Services para registrar servicios web en tiempo de ejecución. Usar servicios de autenticación, perfil y función desde script de cliente Microsoft AJAX Library incluye clases de proxy para llamar directamente a los servicios de aplicación de autenticación de formularios, perfil y funciones de ASP.NET 2.0 desde JavaScript. Si se desea usar un servicio de autenticación personalizado, se puede registrar con el control ScriptManager. Clase ScriptManagerProxy Sólo se puede agregar una instancia del control ScriptManager a la página. La página puede incluir directamente el control o bien indirectamente dentro de un componente anidado como un control de usuario, página de contenido de una página maestra o una página maestra anidada. Si una página ya contiene un control ScriptManager, pero un componente anidado o principal necesita características adicionales del control ScriptManager, el componente puede incluir un control ScriptManagerProxy. Por ejemplo, el control ScriptManagerProxy permite agregar scripts y servicios específicos de los componentes anidados. CONTROL TIMER El control Timer de ASP.NET AJAX realiza devoluciones de datos en intervalos definidos. Al utilizar el control Timer con un control UpdatePanel, se puede habilitar actualizaciones parciales de página en un intervalo definido. También se puede utilizar el control Timer para enviar toda la página. Utilizar el control Timer cuando se desea hacer lo siguiente: Actualizar periódicamente el contenido de uno o varios controles UpdatePanel sin actualizar la página web entera. Ejecutar código en el servidor cada vez que un control Timer origine una devolución de datos. Enviar sincrónicamente la página web entera al servidor web en intervalos definidos. El control Timer es un control de servidor que incrusta un componente JavaScript en la página web. El componente JavaScript inicia la devolución de datos desde el explorador cuando transcurre el intervalo que se define en la propiedad Interval. Las propiedades del control Timer se establecen en código que se ejecuta en el servidor y se pasan al componente JavaScript. Cuando se utilice el control Timer, se debe incluir una instancia de la clase ScriptManager en la página web. Cuando el control Timer inicia una devolución de datos, el control Timer provoca el evento Tick en el servidor. Puede crear un controlador de eventos para que el evento Tick realice acciones cuando la página se envíe al servidor. 103 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Establecer la propiedad Interval para especificar la frecuencia con que deben producirse las devoluciones de datos y establecer la propiedad Enabled para activar o desactivar el control Timer. La propiedad Interval se define en milisegundos y presenta un valor predeterminado de 60.000 milisegundos, o 60 segundos. Nota: Si se establece la propiedad Interval de un control Timer en un valor pequeño, puede generar mucho tráfico al servidor web. Usar el control Timer para actualizar el contenido sólo con la frecuencia necesaria. Se puede incluir más de un control Timer en una página web si es necesario actualizar distintos controles UpdatePanel en intervalos diferentes. Como alternativa, una instancia única del control Timer puede usarse como desencadenador de más de un control UpdatePanel en una página web. CONTROL UPDATE PANEL Los controles de ASP.NET UpdatePanel permiten generar aplicaciones web enriquecidas y centradas en el cliente. Los controles UpdatePanel permiten actualizar las partes seleccionadas de una página en lugar de actualizar toda la página con una devolución de datos. Esto se conoce como actualización parcial de la página. Una página web ASP.NET que contiene un control ScriptManager y uno o varios controles UpdatePanel puede participar automáticamente en actualizaciones parciales de la página, sin un script de cliente personalizado. UpdatePanel es un control de servidor que ayuda a desarrollar páginas web con comportamientos de cliente complejos que hacen que una página web parezca más interactiva al usuario final. Normalmente, escribir código que se coordine entre el servidor y el cliente para actualizar sólo las partes especificadas de una página web requiere un conocimiento detallado de ECMAScript (JavaScript). Sin embargo, con el control UpdatePanel puede hacer que una página web participe de las actualizaciones parciales de la página sin escribir ningún script de cliente. Si se desea, se puede agregar el script de cliente personalizado para mejorar la experiencia del usuario cliente. Cuando se utiliza un control UpdatePanel, el comportamiento de la página es independiente del explorador y puede reducir la cantidad de datos que se transfieren entre el cliente y el servidor. Los controles UpdatePanel trabajan especificando las regiones de una página que se pueden actualizar sin actualizar la página entera. Este proceso se coordina mediante el control de servidor ScriptManager y la clase de cliente PageRequestManager. Cuando están habilitadas las actualizaciones parciales de la página, los controles pueden exponer en el servidor de forma asincrónica. Una devolución de datos asincrónica se comporta como una devolución de datos normal en cuanto que la página de servidor resultante ejecuta la página completa y controla el ciclo de vida. Sin embargo, con una devolución de datos asincrónica, las actualizaciones de la página se limitan a las regiones de la página que están incluidas en los controles UpdatePanel y que están marcadas para actualizarse. El servidor envía el marcado HTML al explorador sólo para los elementos implicados. En el explorador, la clase de cliente PageRequestManager realiza la manipulación del Modelo de objetos de documento (DOM) para reemplazar el código HTML existente por un marcado actualizado. Nota: Al utilizar devoluciones de datos asincrónicas o el objeto XMLHTTPRequest, se puede producir un error de devolución de datos si la dirección URL contiene un carácter de doble byte. Se puede resolver este problema incluyendo un elemento de <base href="url"/> en el elemento head de la página, donde el atributo href está establecido en la cadena con codificación URL que hace referencia a la página. Se puede agregar este elemento agregado dinámicamente en el código de servidor. Habilitar actualizaciones parciales de la página El control UpdatePanel requiere un control ScriptManager en la página web. De forma predeterminada, las actualizaciones parciales de la página están habilitadas porque el valor predeterminado de la propiedad EnablePartialRendering del control ScriptManager es true. Especificar el contenido del control UpdatePanel Se puede agregar contenido a un control UpdatePanel mediante declaración, o bien en el diseñador utilizando la propiedad ContentTemplate. En el marcado, esta propiedad se expone como un elemento ContentTemplate. Para agregar contenido mediante programación, se utiliza la propiedad ContentTemplateContainer. Cuando se representa por primera vez una página que contiene uno o varios controles UpdatePanel, se representa todo el contenido de los controles UpdatePanel y se envían al explorador. En las devoluciones de datos asincrónicas posteriores, el contenido de los controles UpdatePanel individuales podría actualizarse. Las actualizaciones dependen de las opciones de configuración del panel, de qué elemento produjo la devolución de datos y del código específico de cada panel. 104 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 ESPECIFICAR LOS DESENCADENADORES (TRIGGERS) DE UPDATEPANEL De forma predeterminada, cualquier control de devolución de datos dentro de un control UpdatePanel produce una devolución de datos asincrónica y actualiza el contenido del panel. Sin embargo, también puede configurar otros controles de la página para actualizar un control UpdatePanel. Para ello, defina un desencadenador para el control UpdatePanel. Un desencadenador es un enlace que especifica qué evento y control de devolución de datos provoca la actualización de un panel. Cuando se provoca el evento especificado del control desencadenador (por ejemplo, un evento Click de un botón), se actualiza el panel. En el ejemplo siguiente se muestra cómo especificar un desencadenador para un control UpdatePanel. <asp:Button ID="Button1" Text="Refresh Panel" runat="server" /> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server"> <Triggers> <asp:AsyncPostBackTrigger ControlID="Button1" /> </Triggers> <ContentTemplate> <fieldset> <legend>UpdatePanel content</legend> <%=DateTime.Now.ToString() %> </fieldset> </ContentTemplate> </asp:UpdatePanel> El desencadenador se define utilizando el elemento asp:AsyncPostBackTrigger dentro del elemento Triggers del control UpdatePanel. (Editando la página en Visual Studio, se puede crear desencadenadores utilizando el cuadro de diálogo Editor de la colección UpdatePanelTrigger.) El evento de control de un desencadenador es opcional. Si no se especifica un evento, el evento desencadenador es el evento predeterminado del control. Por ejemplo, en el control Button, el evento predeterminado es el evento Click. Cómo se actualizan los controles UpdatePanel En la lista siguiente se describen los valores de las propiedades del control UpdatePanel que determinan cuándo se actualiza el contenido de un panel durante la representación parcial de la página. 105 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Si la propiedad UpdateMode se establece en Always, el contenido del control UpdatePanel se actualiza en todas las devoluciones de datos que se originen desde cualquier parte de la página. Esto incluye las devoluciones de datos asincrónicas de los controles que están dentro de otros controles UpdatePanel y las devoluciones de datos de los controles que no están dentro de los controles UpdatePanel. Si la propiedad UpdateMode es Conditional, el contenido del control UpdatePanel se actualiza cuando se da una de las siguientes condiciones: Cuando un desencadenador produce la devolución de datos para ese control UpdatePanel. Cuando se llama explícitamente al método Update del control UpdatePanel. Cuando se anida el control UpdatePanel dentro de otro control UpdatePanel y se actualiza el panel primario. Cuando la propiedad ChildrenAsTriggers se establece en true y un control secundario del control UpdatePanel provoca una devolución de datos. Los controles secundarios de los controles UpdatePanel anidados no provocan actualizaciones del control UpdatePanel externo a menos que se definan explícitamente como desencadenadores para el panel primario. Si la propiedad ChildrenAsTriggers se establece en false y la propiedad UpdateMode se establece en Always, se inicia una excepción. La propiedad ChildrenAsTriggers está diseñada para usarse sólo cuando la propiedad UpdateMode se establezca en Conditional. Utilizar los controles UpdatePanel en páginas maestras Para utilizar un control UpdatePanel en una página maestra, se debe decidir cómo incluirá el control ScriptManager. Si incluye el control ScriptManager en la página maestra, puede actuar como control ScriptManager de todas las páginas de contenido. (Si desea registrar scripts o servicios mediante declaración en una página de contenido, puede agregar un control ScriptManagerProxy a esa página de contenido.) Si la página maestra no contiene el control ScriptManager, se puede colocar el control ScriptManager individualmente en cada página de contenido que contenga un control UpdatePanel. La opción de diseño depende de cómo se administre el script de cliente en su aplicación. En algunos casos, el control ScriptManager está en la página maestra y no necesita funciones de representación parcial de la página para una página de contenido. En esos casos, debe establecer mediante programación la propiedad EnablePartialRendering del control ScriptManager en false para esa página de contenido. 25 INTERACTUAR CON LA BIBLIOTECA EN EL CLIENTE ASP.NET AJAX: objetos JavaScript Object Notation (JSON); tratamiento de eventos ASP.NET AJAX INTRODUCCIÓN Al diseñar una aplicación que se comunicará con un equipo remoto, se debe seleccionar un protocolo para el formato e intercambio de los datos. Existe una variedad de opciones abiertas y estandarizadas y la elección ideal depende de los requisitos de las aplicaciones y de la funcionalidad preexistente. Por ejemplo, los servicios web basados en SOAP dan formato a los datos en una carga XML contenida en una envoltura SOAP. Aunque en muchos escenarios de aplicación XML funciona bien, presenta ciertos inconvenientes que hacen que no sea ideal. Las aplicaciones web de estilo Ajax son un espacio en que XML no es ideal. Ajax es una técnica usada para crear aplicaciones web interactivas que ofrecen una experiencia de usuario más ágil mediante el uso de llamadas al servidor web, livianas y fuera de banda, en lugar de devoluciones de página completa. Estas llamadas asincrónicas se inician mediante Javascript en el cliente e implican dar formato a los datos, enviarlos a un servidor web, analizar los datos devueltos y trabajar con éstos. Aunque la mayoría de los exploradores pueden crear, enviar y analizar XML, JavaScript Object Notation (JSON) ofrece un formato estandarizado de intercambio de datos más conveniente para aplicaciones web de estilo Ajax. JSON es un formato de intercambio de datos abierto y basado en texto (RFC 4627). Igual que XML, es legible e independiente de la plataforma, además de tener a su disposición una amplia gama de implementaciones. Los datos con formato según el estándar JSON son ligeros y las implementaciones de JavaScript pueden analizarlos sintácticamente con increíble facilidad, lo que lo convierte en el formato ideal de intercambio de datos para aplicaciones web de Ajax. Puesto que JSON es ante todo un formato de 106 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 datos, no está limitado a las aplicaciones web de Ajax y prácticamente se puede usar en cualquier escenario en que las aplicaciones necesiten intercambiar o almacenar información estructurada como texto. UTILIZANDO SINTAXIS JSON CON AJAX JavaScript Object Notation, o JSON, es una sintaxis utilizada para representar datos. JSON es un subconjunto de JavaScript y consiste de pares clave-valor. JSON está basado en texto y utiliza Unicode. JSON anida elementos de datos de una manera similar a XML. Cada instancia de un documento JSON describe un objeto con objetos anidados, arreglos, strings, números, valores booleanos o valores nulos. JSON es ideal para intercambio de datos con Servicios Web. La sintáxis de JSON es definida en http://www.json.org. Existen varias maneras de utilizar JSOB como un formato de intercambio de datos. Para invocar a un servicio desde una página web ASP.Net se añade un elemento ServiceReference a un control ScriptManager. Esto automáticamente genera una clase proxy de JavaScript. Cuando se utiliza una clase proxy para invocar un servicio, JSON es utilizado como un formato de serialización para los datos intercambiandos entre el servidor y el navegador. Las páginas Web que no son ASP.Net .aspx no pueden utilizar un ScriptManager. DEVOLVIENDO DATOS EN UN FORMATO JSON DESDE UN SERVICIO WEB ASP.NET SOBRE HTTP Para habilitar un servicio Web ASP.Net para devolver datos en un formato JSON en HTTP, se puede marcar la clase del Servicio Web con el atributo ScriptService el cual se encuentra en el espacio de nombres Sytem.Web.Script.Services. El atributo ScriptService fue introducido en la versión 3.5 de ASP.Net. El siguiente ejemplo muestra como agregar el atributo ScriptService a la clase del servicio web para habilitar el servicio para devolver los datos en un formato JSON. 1. using System; 2. using System.Web.Services; 3. using System.Web.Script.Services; 4. [WebService(Namespace = "http://tempuri.org/")] 5. [ScriptService] 6. public class Service : System.Web.Services.WebService 7. { 8. [WebMethod] 9. public string HelloWorld() 10. { 11. return "Hello World"; 12. } 13. } Se puede invocar el método del servicio directamente utilizando el método de Sys.Net.WebServiceProxy, como se muestra en el siguiente ejemplo: 1. 2. Sys.Net.WebServiceProxy.invoke("myservice.asmx", "HelloWorld", true, null, succeededCallback, failedCallback); 107 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 El servicio devuelve datos en un formato JSON. Cuando el requerimiento retorna, los datos en formato JSON son evaluados y pasados al objeto o arreglo JavaScript a la función que es especificada en el parámetro succeededCallback. Agregando el atributo ScriptService también habilita al Servicio Web ASP.Net para automáticamente crear una clase de proxy JavaScript. Referenciando el servicio web y agregando “/js” a la referencia del script, se puede causar a ASP.Net a generar la clase de proxy automáticamente. Por ejemplo, si un Servicio Web ASP.Net se encuentra en un archivo llamado Service.asmx, se puede crear la siguiente referencia al script en lenguaje de marcado. 1. <script type="text/javascript" src="service.asmx/js"></script> También es posible guardar la clase de proxy generada de JavaScript colocando en nombre del archivo del servicio web en el navegador con la extensión “/js” y luego almacenando el archivo de proxy cuando se requiera. Esto permite utilizar la clase del proxy del JavaScript para invocar el servicio llamando al método directamente en el objeto proxy. De nuevo, la data formateada en JSON es devuelta, y luego evaluada y psada como un obejto o un arreglo a la función de callback invocada. ENTENDIENDO EL PARÁMETRO ‘D’ EN LOS DATOS ASP.NET AJAX JSON Si se crea una implementación personalizada que devuelve datos en un formato JSON, se debe tener encuenta el potencial hueco de seguridad. La librería de AJAX ASP.Net envuelve los datos formateados para evitar este problema de seguridad. Un arreglo de objetos JSON puede comprometer la página a un posible ataque de los scripts. Enviando un requerimiento a un servicio JSON como un script, es posible obtener los datos de otro dominio ejecutándose en la sección del cliente. Potencialmente, esto podría proveer accesos a otros sitios donde el cliente se encuentra loggeado en un punto en el tiempo. Debido que la respuesta al requerimiento es en JSON, esto es compilado en una instrucción JavaScript. Por ejemplo, si la respuesta es un conjunto de balances de cuentas bancarias: “$1234.56”, “$4567.34”,”6543.76”, un script malicioso podría tener acceso a estos datos debido a ser una instrucción validad JavaScript. Si un script es inyectado en el sitio contoso.com que requiere datos del bancoxxx.com y se lo envía a espia.datos.com, cualquiera que realice un inicio de sesión en espia.datos.com y luego se dirija a contoso.com podría exponer datos sensitivos a la sesión de bancoxxx.com a espia.datos.com La librería AJAX de Asp.Net utiliza el parámetro “d” para formatear los datos JSON. Esto forza a los datos en el ejemplo a aparecer en la siguiente forma, el cual mno es una instrucción JavaScript valida. 1. { "d" : ["$1234.56", "$4567.34", "$6543.76"] } Porque este script no es una instrucción Javascript valida, no puede ser parseada e instanciada como un objeto nuevo en JavaScript. Esto por lo tanto previene los ataques. El formateo con el parámetro “d” es transperante cuando se utiliza la configuración de la opción enableWebScript en conjunto con los atributos webHttpBinding y WebInvoke. El formateo con el parámetro “d” no es utilizado (y por lo tanto, los datos son vulnerables a los huecos de seguridad) cuando se configura el comportamiento del archivo de configuración a webHttp. AJAX DE ASP.NET: INTERIOR DE LA CADENA DE FECHA Y HORA DE JSON El serializador JSON de AJAX en ASP.NET codifica una instancia DateTime como cadena JSON. Durante sus ciclos preliminares, AJAX de ASP.NET usó el formato "@ticks@", donde ticks representa el número de milisegundos desde el 1 de enero de 1970 en Horario universal coordinado (UTC). Una fecha y hora en UTC como el 29 de noviembre de 1989, a las 4:55:30 a. m. se escribiría como "@62831853071@". Aunque es simple y sencillo, este formato no puede distinguir un valor serializado de fecha y hora de una cadena que se parezca a una fecha serializada pero que no esté pensada para ser deserializada como tal. Consecuentemente, el equipo de AJAX de ASP.NET hizo un en la versión final para solucionar este problema al adoptar el formato "\/Date(ticks)\/". El nuevo formato depende de un pequeño truco para reducir la posibilidad de una mala interpretación. En JSON, un carácter de barra diagonal (/) en una cadena se puede escapar con una barra diagonal inversa (\) aunque estrictamente no sea necesario. Para aprovechar esta situación, el equipo de AJAX de ASP.NET modificó JavaScriptSerializer para escribir en su lugar una instancia de DateTime como la cadena "\/Date(ticks)\/". El escape de las dos barras diagonales es superficial, pero importante para JavaScriptSerializer. Según las reglas de JSON "\/Date(ticks)\/" es técnicamente equivalente a "/Date(ticks)/" pero JavaScriptSerializer deserializará la primera como DateTime y la última como String. Por lo tanto, las posibilidades de ambigüedad son considerablemente menores cuando se comparan con el formato más sencillo "@ticks@" de las versiones preliminares. 108 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 26 USAR SERVICIOS DE SCRIPTS DE CLIENTE CONSUMO DE SERVICIOS DE DATOS MEDIANTE LA BIBLIOTECA AJAX DE ASP.NET En la biblioteca Ajax de ASP.NET, existen dos componentes de JavaScript relacionados con los servicios de datos de WCF: OpenDataServiceProxy y OpenDataContext. OpenDataContext está esencialmente diseñado para administrar las operaciones CRUD desde el cliente web. Se puede considerar como la contraparte JavaScript de la clase DataServiceContext. DataServiceContext, definido en el espacio de nombres System.Data.Services.Client, representa el contexto de tiempo de ejecución del servicio de datos de WCF especificado. OpenDataContext hace un seguimiento a los cambios en las entidades que se utilizan y puede generar de forma inteligente comandos con respecto al servicio back-end. La clase OpenDataServiceProxy está diseñada para ser un proxy adicional ligero para un servicio de datos de WCF. Esencialmente administra escenarios de sólo lectura, pero se puede utilizar para invocar operaciones de servicio adicionales expuestas en el servicio. La clase OpenDataServiceProxy se inicializa de la siguiente manera: var proxy = new Sys.Data.OpenDataServiceProxy(url); En este punto, la clase está en funcionamiento. Normalmente, es necesario invertir más tiempo en la configuración de un objeto OpenDataContext. Aunque, en lo que respecta a la conexión al servicio, sucede de una manera similar: var dataContext = new Sys.Data.OpenDataContext(); dataContext.set_serviceUri(url); Ambas clases se pueden usar como proveedores de datos para DataView. El uso de una u otra depende de lo que se desee hacer. Si cualquier actividad CRUD debe suceder mediante el servicio, probablemente sea mejor utilizar un proxy. Si se tiene lógica en el cliente y el propósito es efectuar un grupo de operaciones CRUD antes de aplicar los cambios, entonces se recomienda usar contexto de datos. A continuación se detalla OpenDataContext. USO DE LA CLASE OPENDATACONTEXT A continuación, se indica cómo crear e inicializar una instancia de la clase OpenDataContext: <script type="text/javascript"> var dataContext; Sys.require([Sys.components.dataView, Sys.components.openDataContext]); Sys.onReady(function() { dataContext = Sys.create.openDataContext( { serviceUri: "/NorthwindService.svc", mergeOption: Sys.Data.MergeOption.appendOnly }); }); 109 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 </script> Se debe tener en cuenta el uso de la función Sys.require para vincular de forma dinámica sólo los archivos de script que cumplen el propósito de los componentes que se utilizan. Si se opta por el enfoque Sys.require, el único archivo de script necesario para vincular en la forma tradicional es start.js: <script src="../../Scripts/MicrosoftAjax/Start.js" type="text/javascript"> </script> Sin embargo, todos los archivos que se utilicen deben estar disponibles en el servidor o se debe hacer referencia a ellos a través de la red de entrega de contenido de Microsoft (CDN). En el fragmento code 2, se puede observar que en el evento preparado del documento, se puede crear una nueva instancia de la clase OpenDataContext. Una vez más se debe tener en cuenta el uso de la sintaxis abreviada más reciente para definir código para eventos comunes y crear una instancia de objetos comunes. La fábrica de la clase OpenDataContext recibe la dirección URL del servicio y alguna configuración adicional. En este punto, se está preparado para usar el contexto de datos como el proveedor de datos para algunos componentes de UI DataView de la página, como se muestra en el fragmento code 1. code 1 Uso de contexto de datos como un proveedor de datos <table> <tr class="tableHeader"> <td>ID</td> <td>Name</td> <td>Contact</td> </tr> <tbody sys:attach="dataview" class="sys-template" dataview:dataprovider="{{ dataContext }}" dataview:fetchoperation="Customers" dataview:autofetch="true"> <tr> <td>{{ CustomerID }}</td> <td>{{ CompanyName }}</td> <td>{{ ContactName }}</td> </tr> </tbody> </table> 110 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Una instancia del componente DataView se crea y utiliza para rellenar la plantilla a la cual está adjunto. DataView proporciona el código adjunto necesario para descargar los datos mediante el servicio de datos de WCF y enlazarlos a la plantilla HTML. ¿Dónde se toma la decisión con respecto a los datos que se descargarán? En otras palabras, ¿cómo se especifica la cadena de consulta para los datos que se desean de vuelta? La propiedad de operación de captura del componente DataView indica el nombre de la operación de servicio que se invocará. Si el proveedor de datos es un proxy normal para el servicio, entonces la propiedad fetchoperation adopta el nombre de un método público en el servicio. Si en lugar de eso, se utiliza la clase OpenDataContext, se espera que el valor de fetchoperation sea una cadena que el tiempo de ejecución del servicio de datos de WCF pueda entender. Puede ser una expresión como cualquiera de las siguientes: Customers('ALFKI') Customers('ALFKI')?$expand=Orders Customers('ALFKI')?$expand=Orders&$orderBy=City Si sólo se especifica el nombre de conjunto de entidades válido, se obtendrá la lista completa de entidades. Otras palabras clave, tales como $expand, $orderBy y $filter, permiten incluir conjuntos de entidades relacionados (un tipo de combinación interna), ordenar en una propiedad y filtrar las entidades devueltas en una condición Boolean. La consulta se puede redactar de forma manual como una cadena, pero respetando el formato URI subyacente. O bien, se puede usar el objeto OpenDataQueryBuilder JavaScript integrado, como se muestra en el code 2. Code 2 Uso del objeto AdoNetQueryBuilder <script type="text/javascript"> var dataContext; var queryObject; Sys.require([Sys.components.dataView, Sys.components.openDataContext]); Sys.onReady(function() { dataContext = Sys.create.openDataContext( { serviceUri: "/NorthwindService.svc", mergeOption: Sys.Data.MergeOption.appendOnly }); queryObject = new Sys.Data.OpenDataQueryBuilder("Customers"); queryObject.set_orderby("ContactName"); queryObject.set_filter("City eq " + "’London’"); queryObject.set_expand("Orders"); }); </script> El generador de consultas se puede usar para crear direcciones URL completas o sólo la parte de consulta de la dirección URL. En este caso, el generador de consultas obtiene el nombre del conjunto de entidades para consulta. Además ofrece un grupo de propiedades para establecer cualquier expansión, filtro y pedido necesario. Los criterios establecidos mediante el objeto del 111 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 generador de consultas se deben serializar en una cadena de consulta efectiva cuando esa fetchoperation esté establecida, como se muestra a continuación: <tbody sys:attach="dataview" class="sys-template" dataview:dataprovider="{{ dataContext }}" dataview:fetchoperation="{{ queryObject.toString() }}" dataview:autofetch="true"> Se usa el método toString para extraer la cadena de consulta del generador de consultas. En el código de muestra, la cadena de consulta resultante es Customers?$expand=Orders&$filter="City eq 'London'"&$orderby=ContactName El servicio devuelve una colección de objetos compuestos que incrustan los datos demográficos del cliente más la información de pedido. En el code 3 se muestra el resultado. Code 3 Consulta de datos mediante el uso de un servicio de datos de WCF Los números en la última columna indican el número de pedidos que ha realizado el cliente. Debido al atributo $expand en la consulta, el flujo de datos de JSON contiene una matriz de pedidos. La plantilla HTML hace referencia a la longitud de la matriz y rellena la columna de la siguiente forma: <td>{{ Orders.length }}</td> Es necesario tener en cuenta que para recuperar correctamente la información del pedido, primero se debe volver al código fuente del servicio de datos de WCF y habilitar el acceso al conjunto de entidades Pedidos: public static void InitializeService(IDataServiceConfiguration config) { config.SetEntitySetAccessRule("Customers", EntitySetRights.All); config.SetEntitySetAccessRule("Orders", EntitySetRights.All); } 27 CREAR Y REGISTRAR UN SCRIPT DE CLIENTE: INLINE, ARCHIVO .JS INCLUIDO, RECURSO JAVASCRIPT INCRUSTADO, CREADO DESDE EL CÓDIGO DE SERVIDOR Script de cliente en páginas web ASP.NET Las aplicaciones web ASP.NET no se limitan a las herramientas y lenguajes basados en servidor. Se Puede incluir ECMAScript (JavaScript o JScript) en las páginas web ASP.NET para crear una funcionalidad enriquecida para explorador. ASP.NET dispone de una amplia gama de características para admitir scripts de cliente. Una opción es crear y agregar fragmentos de código individuales de scripts de cliente a las páginas web ASP.NET para admitir el comportamiento de explorador para la aplicación. Esta opción resulta práctica si se desea incluir sólo algunas partes pequeñas de código JavaScript o si está trabajando con un código JavaScript que ya tiene. Esta opción también permite que el tamaño de las páginas web ASP.NET sea el mínimo. Incluir scripts de cliente personalizados en páginas ASP.NET 112 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Debido a que las páginas web ASP.NET simplemente representan marcado HTML, se puede agregar su propio script de cliente. Las páginas ASP.NET admiten secuencias de comandos de cliente en la medida en que el explorador que solicita la página admite dichas secuencias. Si la página se ejecuta en un explorador de un teléfono u otro dispositivo móvil, el grado de compatibilidad con la secuencia de comandos de cliente variará según el explorador. Existen varias opciones para incluir scripts de cliente en páginas ASP.NET: Se puede incluir el script de cliente estáticamente en un bloque script que incluya código o que utilice un atributo include para hacer referencia a un archivo JavaScript (.js). Utilice esta opción para insertar bloques de scripts o archivos JavaScript que contengan scripts de cliente que no sea necesario crear dinámicamente y que no requieran la funcionalidad AJAX adicional que proporciona Microsoft AJAX Library. Se puede crear y agregar dinámicamente el script de cliente a la página web ASP.NET utilizando la clase ClientScriptManager. Utilizar esta opción si desea crear scripts que dependen de información que sólo está disponible en tiempo de ejecución. Si se desea aprovechar las características AJAX de ASP.NET, puede administrar archivos de script de cliente mediante el control de servidor ScriptManager. El control de servidor ScriptManager también garantiza que Microsoft AJAX Library se carga en el explorador antes de que se ejecuten los scripts. Incluir bloques de script de cliente estáticos Se pueden agregar bloques script a una página ASP.NET del mismo modo que se haría con cualquier página HTML. También se pueden utilizar secuencias de comandos de cliente para escribir controladores de eventos para eventos de cliente como el evento onload de la página. Cuando una página ASP.NET se está ejecutando en el explorador, los elementos de marcado de la página son direccionables en el script de cliente. Provocan todos los eventos de cliente igual que en una página HTML. Nota: Se puede hacer referencia a los controles de servidor ASP.NET en el script de cliente. Una página web ASP.NET también puede tener acceso a un archivo de script haciendo referencia a él en el atributo src de una etiqueta <script>, como en el ejemplo siguiente: <script type="text/javascript" src="MyScript.js"></script> Mantener los scripts de cliente en archivos .js externos en lugar de mantenerlos en las páginas ayuda a organizarlos. También hace que sea más fácil administrar el control de versiones y compartirlos entre las páginas. El explorador almacena en memoria caché los archivos .js externos, de forma similar a como se almacenan en memoria caché las páginas web y las imágenes. Una vez que el explorador carga el script como archivo externo, está disponible en la caché para cualquier página web que lo necesite. Esto puede ayudar a aumentar el rendimiento de la aplicación web. Crear scripts de cliente dinámicamente En muchos casos, la secuencia de comandos de cliente para la página se puede crear mediante declaración, normalmente como un bloque de secuencia de comandos. Sin embargo, se pueden crear los scripts de cliente dinámicamente. Esto resulta útil si el script depende de información que sólo está disponible en tiempo de ejecución. Por ejemplo, puede insertar el script de cliente en una página que direcciona un control de servidor cuyo nombre (identificador) no se conoce hasta que se ejecuta la aplicación, o puede crear un script que depende de los valores que recibe de un usuario. Puede crear e insertar dinámicamente el script de cliente en una página representada llamando a los métodos de la clase ClientScriptManager, como se muestra a continuación: RegisterClientScriptBlock , que inserta un bloque de script en la parte superior de la página representada. RegisterStartupScript , que inserta un bloque de script al final de la página representada. Cómo: Agregar secuencias de comandos de cliente a las páginas Web ASP.NET dinámicamente El uso de código del servidor permite agregar secuencias de comandos de cliente a una página. La creación de secuencias de comandos de cliente en el código del servidor es útil cuando el contenido de dichas secuencias depende de información que 113 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 únicamente está disponible en tiempo de ejecución. La adición de secuencias de comandos de cliente a la página de forma dinámica también resulta útil cuando se desea que dichas secuencias se ejecuten en las situaciones siguientes: Cuando la página ha terminado de cargarse Cuando los usuarios envían la página Nota: También se puede agregar eventos de cliente, como onmouseover y onkeyup, a ciertos controles. Para agregar secuencias de comandos de cliente a una página Web ASP.NET dinámicamente en el código del servidor, llamar a uno de los siguientes métodos. RegisterClientScriptBlock Agrega un bloque de secuencias de comandos a la parte superior de la página. Crear la secuencia de comandos como una cadena y, a continuación, pásarla al método, que la agregará a la página. Se puede utilizar este método para insertar cualquier secuencia de comandos en la página. Tener en cuenta que la secuencia de comandos se podría representar en la página antes de que terminen todos los elementos; por consiguiente, es posible que no pueda hacer referencia a todos los elementos de la página desde la secuencia de comandos. RegisterClientScriptInclude Similar al método RegisterClientScriptBlock, pero agrega un bloque de secuencias de comandos que hace referencia a un archivo .js externo. El archivo de inclusión se agrega antes que cualquier secuencia de comandos agregada dinámicamente; por consiguiente, es posible que no pueda hacer referencia a algunos de los elementos de la página. RegisterStartupScript Agrega un bloque de secuencias de comandos a la página que se ejecuta cuando finaliza la carga de ésta, pero antes de que se produzca el evento onload. La secuencia de comandos no se suele crear como un controlador de eventos o una función; generalmente sólo incluye las instrucciones que se deben ejecutar una sola vez. RegisterOnSubmitStatement Agrega una secuencia de comandos que se ejecuta en respuesta al evento onsubmit de la página. La secuencia de comandos se ejecuta antes de que se envíe la página y ofrece la oportunidad de cancelar el envío. En el ejemplo de código siguiente se muestra cómo agregar una secuencia de comandos de cliente a una página que se ejecuta cuando el usuario hace clic en un botón que envía la página de nuevo al servidor. La secuencia de comandos de cliente muestra una ventana emergente que solicita al usuario que confirme la devolución de datos. protected void Page_Load(Object sender, EventArgs e) { String scriptText = "return confirm('Do you want to submit the page?')"; ClientScript.RegisterOnSubmitStatement(this.GetType(), "ConfirmSubmit", scriptText); } 28 PROGRAMAR DISPOSITIVOS MÓVILES El desarrollo de páginas ASP.NET para exploradores de dispositivos móviles no difiere sustancialmente del desarrollo de páginas para los exploradores de escritorio. Para crear aplicaciones para dispositivos móviles, ASP.NET proporciona un espacio de nombres System.Web.Mobile dedicado específicamente al desarrollo Web móvil. Se puede crear una página Web a partir de la clase base MobilePage y agregar controles del espacio de nombres System.Web.Mobile. Este espacio de nombres define una serie de controles de servidor Web y adaptadores que resultan especialmente útiles al crear aplicaciones que deben estar disponibles para muchos dispositivos móviles diferentes, como los teléfonos móviles. ASP.NET 2.0 también proporciona una arquitectura adaptable de controles que permite crear adaptadores de dispositivos personalizados para los controles de servidor Web ASP.NET 2.0. Estos adaptadores crean una representación personalizada para un control basándose en el explorador que realizó la solicitud. Con la arquitectura adaptable, puede utilizar las páginas ASP.NET que 114 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 heredan de la clase base Page (en lugar de las páginas escritas específicamente para dispositivos móviles) y crear adaptadores personalizados para que los controles de servidor Web ASP.NET representen una salida específica en los dispositivos que tienen acceso a la aplicación. En ambos casos, el desarrollo sigue el modelo orientado a eventos de .NET estándar en el que la aplicación responde a las solicitudes del usuario, a los clics en los botones, etc. Arquitectura de las aplicaciones móviles Aunque ASP.NET integra tecnología para que el desarrollo de aplicaciones Web ASP.NET Mobile siga el mismo modelo que el desarrollo de aplicaciones Web tradicional, el objetivo principal de la arquitectura no es permitir crear páginas únicas que se puedan procesar en exploradores de dispositivos de escritorio o de dispositivos móviles. Se puede crear adaptadores para controles de servidor Web ASP.NET individuales o para controles de servidor Web móviles que permitan representar estos controles en exploradores de dispositivos móviles y de escritorio, pero las limitaciones de los exploradores de los dispositivos móviles a menudo implican que las páginas diseñadas para los exploradores de escritorio no se presentan muy bien en los exploradores de dispositivos móviles. Por ejemplo, crear una página Web ASP.NET que incluye un encabezado de sitio, una barra de exploración en la parte superior de la página, una estructura de exploración secundaria a lo largo de la página y contenido en el resto de la página, ésta se representará tal como se ha diseñado en un explorador de escritorio. En este caso, normalmente hay bastante espacio para representar todos los controles y proporcionar un área de contenido desplazable. Sin embargo, en muchos exploradores de dispositivos móviles, este diseño sería imposible. Una gran cantidad de dispositivos móviles disponen de un área de pantalla más pequeña que los monitores de escritorio, por lo que incluso la exploración se convierte en un proceso de varios pasos en el que el usuario debe hacer clic en varios controles para obtener el contenido de la página. La lógica de la presentación sigue un modelo similar. Por ejemplo, cuando el usuario rellena un formulario Web Forms utilizando un explorador de escritorio, puede ver muchos controles en la pantalla al mismo tiempo. Cuando el formulario se valida en el servidor, los errores de validación se pueden mostrar junto a los controles. Con un dispositivo móvil, la introducción de datos en los formularios y la validación de los mismos pueden ser mucho más difíciles de mostrar en un formato que sea utilizable. Además, en los dispositivos móviles podría optar por proporcionar accesos directos que permitan al usuario rellenar información escribiendo menos, ya que es posible que resulte más difícil escribir en esos dispositivos. Por estas razones, se recomienda crear páginas independientes en la aplicación Web ASP.NET para su uso en exploradores de escritorio y de dispositivos móviles. Una página desarrollada específicamente para los exploradores de dispositivos móviles permite dividir la lógica de presentación en partes más pequeñas que funcionen mejor para el área de presentación y el hardware de entrada de datos del dispositivo. Por consiguiente, cuando decida crear este tipo de páginas, debería utilizar controles de servidor Web móviles si la aplicación debe admitir una amplia gama de dispositivos móviles, exploradores que no utilizan HTML o dispositivos con funciones de presentación y entrada de datos limitadas. Controles de servidor Web móviles El espacio de nombres System.Web.Mobile de ASP.NET 2.0 está diseñado específicamente para el desarrollo Web móvil. Se puede crear una página Web móvil a partir de la clase base MobilePage y agregar controles de servidor Web móviles desde el espacio de nombres System.Web.Mobile. Los controles de servidor Web móviles disponen de varios adaptadores especializados en el marco de trabajo y, por consiguiente, están especialmente orientados al desarrollo de aplicaciones Web móviles para una amplia gama de dispositivos móviles. Los controles de servidor Web ASP.NET y la arquitectura de adaptador unificado Todos los controles de servidor Web ASP.NET 2.0 siguen el modelo de arquitectura de adaptador unificado. Esto significa que todos los controles pueden representar datos y comportarse de forma diferente, según el dispositivo solicitante, mediante una llamada a un adaptador personalizado que proporciona los comportamientos apropiados para dicho dispositivo, como la creación del lenguaje de formato adecuado. Si se ha configurado un adaptador en el archivo de definición del explorador para el dispositivo o el explorador solicitante, ASP.NET lo llamará en cada fase del ciclo de vida de un control de servidor Web. De esta manera, el adaptador podrá ajustar el resultado representado y controlar la lógica de estado de vista específica del dispositivo o las características individuales del dispositivo. Los archivos de definición del explorador se encuentran en la carpeta Browsers del directorio Config de .NET Framework o en la carpeta App_Browsers de una aplicación Web. Se puede crear adaptadores personalizados para cada dispositivo y hacer que el marco de trabajo de páginas ASP.NET los utilice cuando un dispositivo concreto tenga acceso a su página. 115 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Elegir adaptadores personalizados o controles móviles Para la mayoría de desarrolladores de páginas, el método recomendado para el desarrollo móvil consiste en utilizar controles de servidor Web móviles y crear páginas que heredan de MobilePage. Estos controles admiten muchos dispositivos móviles, como los teléfonos móviles. ASP.NET incluye controles de servidor Web móviles para una amplia gama de necesidades específicas de los entornos móviles y de desarrollo Web en general. Además, ya existen adaptadores de dispositivos para controles móviles para los principales dispositivos y sus lenguajes de formato. Microsoft continuará proporcionando actualizaciones de los adaptadores para los controles de servidor Web móviles cuando evolucionen los principales lenguajes de formato. Esto le permitirá admitir nuevos lenguajes de formato con los mismos controles que está utilizando en la actualidad. Por ejemplo, si se está creando un sitio de comercio electrónico que admite exploradores de escritorio, así como una amplia gama de dispositivos móviles, el método recomendado consiste en crear un conjunto de páginas ASP.NET que hereden de la clase Page y otro conjunto de páginas que hereden de la clase base MobilePage y utilicen controles móviles. Esto proporcionará compatibilidad con los dispositivos móviles sin necesidad de crear adaptadores personalizados. Asimismo, los controles de servidor Web móviles siguen el modelo de arquitectura de adaptador unificado, por lo que, si es necesario, puede crear sus propios adaptadores personalizados o modificar los existentes, ya que los nuevos dispositivos determinarán nuevos requisitos de comportamiento en los controles de servidor Web móviles. Hay escenarios en los que tiene sentido el uso de controles de servidor Web ASP.NET y la escritura de adaptadores personalizados. Generalmente, éstos serán aplicaciones para exploradores de escritorio completos en los que son necesarias variaciones de comportamiento en función del explorador o aplicaciones orientadas a cierto tipo de dispositivos muy particulares para los que no se garantizan los controles móviles y su conjunto de características. Por ejemplo, imagine que está creando una aplicación de reclamaciones de seguros que tiene una interfaz basada en explorador para su uso en la oficina y una interfaz para diversos dispositivos para su uso fuera de la oficina. Esta aplicación podría utilizar las mismas clases de página base para las páginas normales y las páginas para diversos dispositivos. Únicamente debería crear adaptadores personalizados para el dispositivo que se ha implementado fuera de la oficina. Una ventaja de la creación de adaptadores personalizados para los controles de servidor Web ASP.NET es que permite utilizar la clase base Page para las páginas Web y aprovechar por completo el conjunto de características de ASP.NET 2.0. ASP.NET MOBILE WEB FORMS Y COMPATIBILIDAD CON ASP.NET Cuando se crean páginas Web de ASP.NET Mobile, se pueden utilizar casi todas las funciones de ASP.NET. Sin embargo, antes conviene considerar algunas cuestiones relacionadas con la compatibilidad. Control e informes de errores Cuando una aplicación ASP.NET encuentra una excepción no controlada o cualquier otro error al procesar una solicitud, genera una página de error. Las excepciones pueden producirse en cualquier momento del procesamiento de una solicitud. Por ejemplo, en la lectura de un archivo de configuración (Web.config), en la compilación o ejecución de una página, etc. Se puede configurar la aplicación para que se generen páginas de error predeterminadas o personalizadas. Si se configura para que se generen páginas de error predeterminadas, ASP.NET establece un código de error en la respuesta y representa una página que describe detalladamente el error. Sin embargo, si la configura para que se generen páginas de error personalizadas, cada solicitud de error se redirige a una página personalizada que se proporciona para tal fin. Muchos dispositivos móviles no pueden representar el contenido detallado de una página de error. En su lugar, dichos dispositivos suelen mostrar únicamente un mensaje de error específico de un dispositivo, o el código de error. Para tratar esta situación, las páginas de ASP.NET Mobile Web Forms intentan dar a la página de error un formato que permita la representación en el dispositivo. Sin embargo, esta representación específica de un dispositivo se limita a las excepciones que se producen durante la ejecución de la página. Por tanto, si está utilizando páginas de error predeterminadas, debe intentar primeramente que la página de formularios Mobile Web Forms de un explorador de escritorio detecte posibles errores de configuración o de compilación. 116 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Si se piensa utilizar páginas de error personalizadas en la aplicación Web ASP.NET Mobile, ASP.NET puede dar a la página de error el formato apropiado para dispositivos móviles diferentes si va a escribir las páginas de error personalizadas utilizando controles móviles. Seguimiento ASP.NET proporciona una funcionalidad de fácil uso denominada Seguimiento que se puede utilizar para depurar las aplicaciones Web. ASP.NET proporciona dos niveles de seguimiento: seguimiento en el nivel de página y seguimiento en el nivel de aplicación. El primero proporciona información de seguimiento como código HTML que se anexa a cada página objeto de seguimiento, mientras que el segundo proporciona información de seguimiento a través de una dirección URL asignada especial (Trace.axd) en la aplicación. Si utiliza seguimiento en el nivel de página en la aplicación Web ASP.NET Mobile, el código HTML anexado a la representación puede evitar que se represente el resultado en el dispositivo móvil. Si embargo, en aplicaciones Web ASP.NET Mobile, debe utilizar seguimiento en el nivel de aplicación e inspeccionar el resultado del seguimiento desde un explorador Web de escritorio. Estado de la sesión y cookies ASP.NET proporciona funciones avanzadas de administración de sesiones que permiten mantener fácilmente el estado a través de solicitudes. Normalmente, la función de estado de la sesión de ASP.NET utiliza cookies en el explorador, pero se puede configurar para que trabaje sin cookies. En ASP.NET, se puede utilizar Session para guardar información relativa a una sesión de usuario a través de varias solicitudes. La administración de sesiones de ASP.NET es escalable y sólida, pudiéndose utilizar incluso en baterías de servidores Web. De forma predeterminada, Session de ASP.NET utiliza una cookie de cliente para almacenar un identificador en el equipo cliente. Se puede utilizar el identificador para localizar una sesión en acciones de ida y vuelta. Además, Session de ASP.NET admite un modo de sesión sin cookies que redirige inicialmente un cliente a una dirección URL nueva que contiene un identificador de sesión. El identificador de sesión se analiza automáticamente fuera de la dirección URL. Al escribir una aplicación Web ASP.NET Mobile, se debe tener en cuenta que algunos dispositivos móviles y puertas de enlace inalámbricas no admiten cookies. Para agregar compatibilidad para estos dispositivos, se debe configurar la aplicación de modo que se utilicen sesiones sin cookies. Consideraciones a tener en cuenta al utilizar el estado de la sesión Cuando se escribe una aplicación Web ASP.NET Mobile que utiliza la administración del estado de la sesión, se han de considerar los factores siguientes: No se permite el uso de controles de ASP.NET en el espacio de nombres System.Web.UI.WebControls en una página de formularios Mobile Web Forms. Las páginas de formularios Mobile Web Forms que utilizan controles Web móviles del espacio de nombres System.Web.UI.MobileControls permiten establecer el atributo EnableSessionState de la directiva @ Page en false. Sin embargo, las páginas de formularios Mobile Web Forms que utilizan un control ASP.NET del espacio de nombres System.Web.UI.WebControls con EnableSessionState establecido en false pueden generar errores en tiempo de compilación. Algunos dispositivos móviles y puertas de enlace no admiten cookies. Para permitir que una página de formularios ASP.NET Mobile Web Forms se ejecute en estos dispositivos, establezca el atributo cookieless del elemento sessionState en true. Algunos dispositivos móviles tienen problemas en el tratamiento de direcciones URL relativas después de haber sido redirigidos mediante la técnica empleada por la administración de sesiones sin cookies. Por ejemplo, si un explorador Openwave abre un archivo .aspx en http://localhost/a.aspx, y el sitio Web redirige el explorador a /12345678/a.apsx, el explorador sigue considerando su ruta de acceso actual como raíz. El explorador solicitará una referencia relativa posterior a b.aspx como /b.aspx. La solución consiste en incluir una dirección URL raíz en la página, como /12345678/a.aspx, en lugar de una dirección URL relativa cuando se efectúa la representación después de una redirección. Los controles de ASP.NET Mobile integrados realizan esta acción automáticamente, pero los adaptadores o los controles que acaban de escribirse deben incluir código que trate la representación después de una redirección. Tanto MobilePage como las clases base de adaptador tienen métodos, como MakePathAbsolute, que ayudan a un desarrollador de controles móviles a escribir direcciones URL raíz. 117 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Utilizar redirecciones Algunos dispositivos y exploradores requieren actualmente direcciones URL completas en respuesta a una redirección para HTTP. Establezca el atributo useFullQualifiedRedirectUrl del elemento httpRuntime en true en la sección System.Web del archivo Machine.config o del archivo Web.config (en el nivel de aplicación). Problemas de sintaxis La sintaxis que es válida en ASP.NET, por ejemplo <%=, no es válida en los controles ASP.NET Mobile, y se debe reemplazar por mecanismos de enlace de datos. Las expresiones de enlace de datos se deben delimitar mediante <%# y %>. 29 ACCESO A LAS CAPACIDADES DEL DISPOSITIVO: TRABAJO CON EMULADORES Cómo: Trabajar con emuladores y exploradores Los controles de ASP.NET Mobile permiten desarrollar aplicaciones para una gran variedad de dispositivos móviles. Los fabricantes de la mayoría de dispositivos móviles proporcionan emuladores que simulan el funcionamiento del hardware y de los exploradores. El software emulador permite ver las páginas Web de ASP.NET Mobile tal y como se verían en los dispositivos de hardware de los fabricantes, así como probar la interfaz del sitio Web tal y como lo harían los usuarios. Es posible, por ejemplo, que después de comprobar cómo se desplazaría un usuario por su sitio Web en un dispositivo determinado, se decida modificar la interfaz y utilizar una plantilla DeviceSpecific para ese dispositivo. Al utilizar emuladores en las fases de desarrollo y comprobación, resulta más fácil evaluar la aplicación Web móvil en una gran variedad de dispositivos antes de llevar a cabo su implementación. Existen dos planteamientos para ver las páginas Web móviles en los emuladores de dispositivos: Instalar y utilizar los emuladores de dispositivos proporcionados por los fabricantes. Utilizar los emuladores que se instalan con algunas ediciones de Visual Studio. Para utilizar esta opción, debe tener una edición de Visual Studio que contenga el Administrador de emuladores de dispositivos y haber instalado la aplicación ActiveSync, que puede descargar desde la página de herramientas de Windows Mobile Developer Center. Agregar un emulador a Visual Studio Se puede agregar un emulador a la lista de exploradores disponibles de Visual Studio. Para agregar el emulador de un fabricante de dispositivos a la lista de exploradores disponibles 1. 2. Compilar la aplicación. Instalar el emulador de dispositivos móviles en el PC de desarrollo. Consultar las instrucciones contenidas en la documentación del emulador. 3. En el menú Archivo, Clic en Explorar con. Visual Studio muestra el cuadro de diálogo Explorar con. 4. Clic en Agregar.Visual Studio muestra el cuadro de diálogo Agregar programa. 5. En el cuadro Nombre del programa, especificar el nombre del archivo del programa ejecutable del emulador. 6. Si el emulador admite argumentos de línea de comandos, especificar estos argumentos en el campo Nombre del programa. Por ejemplo, utilizar %startpage para especificar dónde se debe sustituir la página de inicio de la aplicación en la línea de comandos. 7. En el cuadro Nombre descriptivo, escribir el nombre del explorador tal y como desea que aparezca en Visual Studio. 8. Clic en Aceptar. 9. Si desea que el emulador sea el explorador predeterminado, Clic en Establecer como predeterminado. 10. Clic en Cerrar. Quitar un emulador Si se deja de necesitar un emulador, se puede quitar de Visual Studio. Para quitar un emulador de la lista de exploradores 118 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 1. En el Explorador de soluciones, Clic con el botón secundario del mouse en cualquier archivo .aspx. 2. En el menú contextual, haga clic en Explorar con. El diseñador muestra el cuadro de diálogo Explorar con. 3. Seleccionar un emulador de la lista de exploradores. 4. Clic en Quitar. Visual Studio quita el nombre del emulador de la lista de exploradores. Nota No obstante, no se podrá quitar el explorador designado como explorador predeterminado. Probar páginas con el Administrador de emuladores Todas las ediciones de Visual Studio son compatibles con las páginas Web móviles. Si la edición de Visual Studio también es compatible con aplicaciones de dispositivos móviles (como Pocket PC), tendrá instalado el Administrador de emuladores, que contiene varios emuladores. Sin embargo, los emuladores disponibles en el Administrador de emuladores no se diseñaron para realizar pruebas en páginas Web móviles. Si se desea utilizar el Administrador de emuladores para probar sus páginas Web móviles, se puede instalar ActiveSync, que está disponible para su descarga en la página de herramientas de Microsoft Mobile Developer Center. Si se desea ver su sitio Web con un emulador mediante el Administrador de emuladores 1. 2. Compilar la aplicación. En el menú Herramientas, Clic en Administrador de emuladores. Nota: Si el comando Administrador de emuladores no está disponible, significa que no se tiene instalado Compact Framework. 3. Seleccione un emulador de dispositivos. 4. En el menú Acciones, haga clic en Conectar. Se abre el emulador. Mover el emulador para poder ver el Administrador de emuladores y esperar a que le indique que el dispositivo seleccionado está conectado. 5. En el Administrador de emuladores, clic con el botón secundario del mouse en el emulador de dispositivos conectados de la lista y, en el menú contextual, clic en Colocar en la base. Se inicia ActiveSync. 6. En el cuadro de diálogo Configurar una asociación, seleccione Asociación como invitado y hacer clic en Siguiente. 7. Cuando ActiveSync indicar que el dispositivo está conectado, ciérrelo. Seguirá ejecutándose en segundo plano. 8. En el emulador, desplácese a su sitio Web. Nota: Es posible que el emulador no pueda utilizar una dirección URL del host local para obtener acceso al proyecto del sitio Web. De no ser así, se podrá ver el sitio Web utilizando la dirección URL de la intranet. Depurar páginas Web en el emulador Si Visual Studio no es capaz de iniciar un emulador al depurar un sitio Web, la aplicación se puede depurar asociándola al proceso de trabajo de ASP.NET. Para depurar la aplicación de sitio Web asociándola al proceso de trabajo 1. 2. 3. 4. 5. 6. Definir un punto de interrupción en el código que desea depurar. Compilar la aplicación. En el menú Herramientas, seleccione Asociar al proceso. En la lista Procesos disponibles, seleccione el proceso de trabajo del sitio Web (w3wp.exe o aspnet_wp.exe). Hacer clic en Asociar. Se inicia el depurador de Visual Studio. En el emulador o en el explorador, desplácese hasta su proyecto de sitio Web. El depurador se detiene en el primer punto de interrupción. 30 CONTROLAR EL PROCESAMIENTO ESPECÍFICO DEL DISPOSITIVO: CONTROL DEVICESPECIFIC; FILTROS DE DISPOSITIVO; PLANTILLAS DE CONTROL Métodos de evaluación de dispositivos Los métodos de evaluación de dispositivos permiten crear filtros con nombre para los controles de ASP.NET Mobile que se pueden usar directamente en el método HasCapability. Asimismo, estos filtros se pueden usar de forma indirecta en el archivo Web.config, mediante el elemento <Choice> de la sección <DeviceSpecific>. 119 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Para especificar un filtro con nombre, es preciso agregar una entrada en la sección <deviceFilters> del archivo Web.config. En el ejemplo siguiente se muestra cómo se define un filtro de dispositivo denominado isHTML32. <filter name="isHTML32" compare="PreferredRenderingType" argument="html32" /> En tiempo de ejecución, este filtro compara el valor de la propiedad PreferredRenderingType de la instancia MobileCapabilities de la solicitud actual con el valor html32. En el ejemplo siguiente se muestra cómo definir una nueva función denominada GPSEnabled. namespace MyNamespace { public class MyCapabilityEvaluators { public static bool IsGPSEnabled( System.Web.Mobile.MobileCapabilities capabilities, String unusedArg) { // processing code } } } Escribir el elemento siguiente en el archivo Web.config apropiado para agregar la nueva función: <deviceFilters> <filter name="GPSEnabled" type="MyNamespace.MyCapabilityEvaluators, MyAssembly" method="IsGPSEnabled" /> </deviceFilters> Durante la representación, se selecciona una de las opciones de un elemento <DeviceSpecific> en función de las características del dispositivo de destino. La comparación comprueba primero si el nombre del filtro está entre los definidos para la página. Si existe un método con la firma adecuada en el archivo Web.config o en la jerarquía de configuración, se utiliza dicho método para evaluar la entrada <Choice> en busca de un filtro con el nombre apropiado. El filtrado de dispositivos permite personalizar algunos aspectos de la representación de los controles de servidor Web según el explorador o el dispositivo en que se vayan a visualizar. Cuando un usuario solicita una página Web de un servidor, el explorador realiza una solicitud que contiene información, como el agente de usuario y otros encabezados, que identifican el tipo y versión del explorador. De este modo, ASP.NET puede establecer la correspondencia entre el identificador y un dispositivo determinado definido en un archivo de explorador. Entonces el resultado se puede filtrar en función del dispositivo mediante el identificador de los controles de servidor Web. 120 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Filtrado de dispositivos En el siguiente ejemplo de código declarativo se muestra el uso de un filtro de dispositivo para acortar la propiedad de texto de un control Label de un dispositivo Pocket PC en el que se está ejecutando Pocket Internet Explorer. Éste es un uso común de un filtro de dispositivos: proporcionar texto más conciso para un dispositivo cuyo tamaño de pantalla es reducido. El prefijo "PIE" que aparece delante del segundo atributo Text especifica que el control debe representar esa versión del texto si el identificador del explorador solicitante es "PIE". <asp:Label runat="server" id="title" Text="Welcome to Our Online Shopping Catalog" PIE:Text="Welcome, Shopper" /> Filtros de controles Se puede filtrar el resultado de los controles para dispositivos diferentes aplicando filtros a los elementos siguientes: Propiedades de los controles Atributos personalizados Plantillas Filtros de dispositivos para las directivas También se puede aplicar filtros de dispositivos a los atributos de la directiva @ Page para que se adapte mejor a las funciones de cada dispositivo. Por ejemplo, se puede deshabilitar el estado de vista para determinados dispositivos o utilizar temas diferentes en función del dispositivo que tiene acceso a la página. Algunas de las directivas @ Page que se pueden filtrar son las siguientes: Buffer ClientTarget CodePage ContentType Culture EnableViewState EnableViewStateMac ErrorPage LCID MasterPageFile ResponseEncoding Theme UICulture Si se está trabajando con controles de usuario, también se puede aplicar filtros de dispositivos a los atributos de la directiva @ Control. En general, aunque la directiva @ Control ofrece menos atributos para los que tiene sentido el filtrado de dispositivos, se puede aplicar a atributos como EnableViewState. Por último, se puede aplicar atributos de filtros de dispositivos, utilizados para especificar la propiedades de una página principal, en la directiva @ Master. Nota: En el archivo Web.config no se pueden especificar filtros de dispositivos. 31 AGREGAR CONTROLES WEB MÓVILES A UNA PÁGINA WEB: CONTROLES STYLESHEET; CONTROLES LIST; CONTROLES CONTAINER Espacios de nombres ASP.NET para controles móviles Microsoft ASP.NET proporciona tres espacios de nombres que se utilizan para implementar el comportamiento de controles y componentes móviles en tiempo de diseño y en tiempo de ejecución. Estos espacios de nombres incluyen las interfaces y las clases base fundamentales para implementar atributos, clases, controles y elementos. A continuación se enumeran los espacios de nombres de ASP.NET para controles móviles y las clases que los constituyen: 121 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 System.Web.Mobile. Clases principales de funciones, autenticación y control de errores. Clases MobileCapabilities y MobileFormsAuthentication. System.Web.UI.MobileControls. Clases principales de controles ASP.NET Mobile. Interfaces IObjectListFieldCollection, ITemplateable. Clases AdRotator y DeviceSpecific. System.Web.UI.MobileControls.Adapters. Clases principales de adaptadores que se pueden implementar para crear adaptadores para dispositivos de destino Control StyleSheet Un control StyleSheet puede contener cualquier número de objetos de estilo u objetos de estilo más especializados que heredan de la clase Style. Éstos deben tener propiedades de nombre único. Se puede hacer referencia a continuación a otros controles en la misma página por su propiedad Name. Esta clase no tiene ninguna representación visual. Una página también puede utilizar una hoja de estilos externa y varias páginas pueden compartir la misma hoja de estilos externa. Elemento <Style> , tema Styles. Nota: El control StyleSheet omite sus propios atributos de estilo; establecer un atributo de estilo en el control StyleSheet no tiene ningún efecto en los estilos contenidos como elementos secundarios dentro del control StyleSheet. Control List Representa una lista de elementos como una presentación estática o una lista interactiva. Este control admite la representación con plantilla utilizando los juegos de plantillas de dispositivo y la paginación interna. Control Container 32 IMPLEMENTAR ADAPTADORES DE CONTROL: App_Browsers; procesamiento utilizando ChtmlTextWriter o XhtmlTextWriter La clase HtmlTextWriter se usa para representar HTML 4.0 en exploradores de escritorio. La clase HtmlTextWriter es también la clase base para todos los sistemas de escritura de marcado del espacio de nombres System.Web.UI, incluidas las clases ChtmlTextWriter, Html32TextWriter y XhtmlTextWriter. Estas clases se usan para escribir los elementos, atributos y la información de estilo y diseño de los distintos tipos de marcado. Además, estas las clases de adaptación de página y de control asociadas a cada lenguaje de marcado usan estas clases. En la mayor parte de los casos, ASP.NET usa automáticamente el sistema de escritura apropiado para el dispositivo que realiza la solicitud. Sin embargo, si se crea un escritor de texto personalizado o desea especificar un escritor concreto para representar una página para un dispositivo concreto, debe asignar el sistema de escritura a la página en la sección controlAdapters del archivo .browser de la aplicación. Tipos de adaptadores Para facilitar la compatibilidad con varios dispositivos, la arquitectura de páginas Web de ASP.NET Mobile se basa en un modelo de adaptadores de dispositivos. Las páginas Web móviles y los controles ASP.NET Mobile son de por sí independientes del dispositivo, pero un conjunto de adaptadores de dispositivo debidamente elegidos proporciona una capa de presentación específica del dispositivo para las páginas y controles móviles. Los adaptadores de dispositivos están asociados a combinaciones de controles independientes y dispositivos de destino. Para un dispositivo dado, cada clase de controles móviles puede tener asociada una única clase de adaptadores de controles, y cada instancia de un control está enlazada a una instancia correspondiente de un adaptador. Para cada tipo de dispositivo, se pueden definir las clases siguientes: Clase base de adaptadores de controles. Clase base de la que heredan todos los adaptadores de dispositivos. Adaptador de página. Adaptador asociado a la página. Adaptador de formularios. Adaptador de controles asociado a cada formulario de la página. Adaptadores de controles. Clases de adaptadores de controles que se corresponden con los controles del sistema. Sistema de escritura de texto. Clase que hereda de la clase HtmlTextWriter y que contiene métodos auxiliares específicos del destino. 122 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Como norma, si alguna funcionalidad precisa el contexto de un control, se debe considere la posibilidad de situarlo en la clase base de adaptadores de controles. Clase base de adaptadores de controles Cada conjunto de adaptadores de dispositivos incluye normalmente una clase base para todos los adaptadores del conjunto. La clase base ControlAdapter proporciona funcionalidad utilizada comúnmente y específica de la clase de dispositivos. Por lo general, esto consiste en métodos auxiliares que requieren contexto de control o de página. Entre estos métodos auxiliares se incluyen: Métodos para representar eventos de devolución de datos de controles. Métodos que representan propiedades de estilo del control. Las propiedades de estilo se tratan de forma distinta para cada dispositivo; por tanto, cada adaptador tiene una implementación diferente para la representación de los estilos. Métodos que se pueden reemplazar y que proporcionan información específica del dispositivo al marco de trabajo de páginas ASP.NET, o a adaptadores de la página o formulario contenedor. Propiedades convenientes para obtener acceso a adaptadores de la página o formulario contenedor. Es aconsejable que la clase base de adaptadores de controles que se proporcione herede también de la clase ControlAdapter, que es una clase base general. Esta clase proporciona una implementación predeterminada de la interfaz IControlAdapter que requieren todos los adaptadores. Se recomienda que la implementación de la representación predeterminada de la clase base represente todos los controles secundarios. Esto permite utilizar la clase base como adaptador para los controles compuestos. Clase de adaptadores de páginas Cada conjunto de adaptadores de dispositivos tiene una clase de adaptadores de páginas que está asociada a la página móvil. Cada instancia de una página móvil, o cada clase de páginas heredada de un objeto MobilePage, está enlazada a un adaptador de página específico del dispositivo de destino. Un adaptador de páginas contiene normalmente lo siguiente: Funcionalidad de estado de vista y de devolución de datos específica del dispositivo. Métodos que guardan y cargan el estado de controles específico del dispositivo; por ejemplo, información sobre la paginación. Código de inicialización que prepara la respuesta devuelta al cliente. Esto incluye el establecimiento del tipo MIME de la respuesta en el formato apropiado. Método Render que representa la estructura de la página devuelta al cliente. Por ejemplo, los adaptadores de páginas basados en HTML suelen representar por lo menos las etiquetas <html> de apertura y cierre. Otras funciones en el nivel de página específicas del dispositivo, tales como ensamblar un adaptador de páginas para un dispositivo que admita la posibilidad de devolver varias páginas en una sola respuesta. Una clase de adaptadores de páginas debe proporcionar una implementación completa de la interfaz IPageAdapter. Normalmente, la clase de adaptadores de páginas que se escriba debe heredar también de la clase de adaptadores de controles apropiada. Por ejemplo, si está escribiendo únicamente para un dispositivo basado en WML, desearía heredar de la clase WmlControlAdapter. Clase de adaptadores de formularios Cada conjunto de adaptadores de dispositivos tiene también una clase de adaptadores de formularios que está asociada a la clase Form. Cada instancia de un formulario está enlazada a un adaptador de formularios que es específico del dispositivo de destino. Un adaptador de formularios contiene normalmente lo siguiente: Métodos que tratan la interactividad entre formularios específica del dispositivo. Métodos que tratan la adaptación de un único formulario a distintos dispositivos. Esto podría incluir código para paginar un formulario o para combinar elementos de formulario en un menú. Un método Render que representa la estructura del formulario. Por ejemplo, los adaptadores de páginas basados en WML suelen representar por lo menos las etiquetas <card> de apertura y cierre. Clase de escritores de texto La clase de sistema de escritura de texto no es una clase de adaptador, sino una clase que hereda de la clase System.Web.UI.HtmlTextWriter. Para llevar a cabo la representación, se crea y se pasa mediante cada adaptador una instancia 123 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 de la clase de escritores de texto; es decir, todo el proceso de representación se realiza a través de este objeto. El sistema de escritura de texto contiene normalmente métodos auxiliares para ejecutar tareas tales como la codificación de los datos. ChtmlTextWriter (Clase) Escribe una serie de caracteres específicos de cHTML y texto en la secuencia de salida de un control de servidor ASP.NET. La clase ChtmlTextWriter proporciona funciones de aplicación de formato que los controles de servidor ASP.NET utilizan al enviar contenido cHTML a los clientes. El HTML compacto, o cHTML, es un subconjunto de HTML 2.0, HTML 3.2 y HTML 4.0 diseñado para su uso en dispositivos con memoria y rendimiento de CPU limitados, pantallas pequeñas, capacidades de formato reducidas y un número limitado de opciones de entrada (como el teclado de un teléfono móvil). Por lo tanto, cHTML no admite los siguientes elementos: Imágenes JPEG. Tablas. Mapas de imagen. Varias fuentes y estilos de caracteres. Colores e imágenes de fondo. Marcos. Hojas de estilo. La clase ChtmlTextWriter deriva de la clase Html32TextWriter y gran parte de su funcionalidad la proporcionan la clase Html32TextWriter y la clase base de todos los escritores de texto de marcado, que es la clase HtmlTextWriter. Ejemplo En el siguiente ejemplo de código se muestra la forma de crear una clase denominada CustomChtmlTextWriter derivada de la clase ChtmlTextWriter. Crea dos constructores y reemplaza el método OnAttributeRender para evitar que el atributo de estilo bgcolor se escriba en la secuencia de salida del objeto ChtmlTextWriter. También crea una clase denominada ChtmlCustomPageAdapter que define un método, CreateCustomChtmlTextWriter, que crea y devuelve una instancia de la clase CustomChtmlTextWriter. Después, el objeto CustomChtmlTextWriter representa el contenido cHTML de una página en los dispositivos con exploradores que utilizan el marcado de cHTML. // Create a class that derives from the // ChtmlTextWriter class. using System; using System.IO; using System.Web.UI; using System.Web.UI.WebControls.Adapters; namespace AspNet.Samples.CS { public class CustomChtmlTextWriter : ChtmlTextWriter { // Create two constructors for the new // text writer. public CustomChtmlTextWriter(TextWriter writer) : base(writer, DefaultTabString) { } public CustomChtmlTextWriter(TextWriter writer, String tabString) : base(writer, tabString) { } // Override the OnAttributeRender method to // not render the bgcolor attribute, which is // not supported in CHTML. protected override bool OnAttributeRender(string name, string value, HtmlTextWriterAttribute key) { if (String.Equals("bgcolor", name)) { return false; 124 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 } } } } // Call the ChtmlTextWriter version of the // the OnAttributeRender method. return base.OnAttributeRender(name, value, key); // Derive from the WebControlAdapter class, // provide a CreateCustomChtmlTextWriter // method to attach to the custom writer. public class ChtmlCustomPageAdapter : WebControlAdapter { protected internal ChtmlTextWriter CreateCustomChtmlTextWriter( TextWriter writer) { return new CustomChtmlTextWriter(writer); } } XhtmlTextWriter (Clase) Escribe los caracteres específicos del lenguaje de marcado de hipertexto extensible (XHTML), incluyendo todas las variaciones de módulos XHTML que derivan de XTHML, en el flujo de salida para un control de servidor ASP.NET para los dispositivos móviles. Reemplazar la clase XhtmlTextWriter para proporcionar una representación XHTML personalizada para las páginas ASP.NET y controles de servidor. XHTML es un lenguaje de marcado compatible con XML, que se basa en HTML 4.1, y permite crear los sitios Web convenientes para varios tipos de dispositivo. Combina la facilidad de uso del HTML con las instrucciones de elemento estrictas proporcionadas por XML para generar un lenguaje de marcado con una gama amplia de opciones de formato y de estilo, y menor ambigüedad de la etiqueta de marcado. La clase XhtmlTextWriter incluye funciones de aplicación de formato que los controles de servidor de ASP.NET utilizan al representar contenido XHTML en los clientes. Se puede utilizar el método SetDocType para especificar qué tipo de XHTML representa el sistema de escritura de texto. Los tipos de documento compatibles se definen en la enumeración XhtmlMobileDocType. La clase XhtmlTextWriter representa dos conjuntos de atributos de elementos. Un conjunto es una colección de atributos comunes, según la referencia que consta en la propiedad CommonAttributes. El segundo conjunto es una colección de atributos específicos del elemento, según la referencia que consta en la propiedad ElementSpecificAttributes. Se puede utilizar los miembros de la clase XhtmlTextWriter y cualquier clase derivada para crear los sistemas de escritura de texto personalizados que se usarán en adaptadores de página o de clase personalizados de XHTML. También se puede crear clases derivadas que reemplacen el comportamiento estándar de la clase XhtmlTextWriter. De manera predeterminada, cuando se está trabajando con exploradores que admiten HTML 4.0, los controles y las páginas ASP.NET representan el marcado que es compatible con XHTML 1.1 estándar. El objeto HtmlTextWriter envía XHTML a menos que configure específicamente ASP.NET para no representar el marcado XHTML Ejemplo de Código El ejemplo de código en esta sección contiene cuatro partes. En el primer ejemplo se muestra cómo se crea una clase derivada. En el segundo ejemplo de código se muestra cómo se crea un control personalizado. En el tercer ejemplo de código se muestra cómo utilizar el control personalizado. El cuarto ejemplo de código incluye el código requerido para ejecutar el control personalizado. En el ejemplo de código siguiente se muestra la forma de crear una clase personalizada que deriva de la clase XhtmlTextWriter. Tiene dos constructores, estándar para todas las clases, que heredan directa o indirectamente de la clase HtmlTextWriter. El primer constructor toma un objeto TextWriter como parámetro, llama al segundo constructor y le pasa los dos valores de parámetro siguientes: Instancia de TextWriter. Valor de la propiedad HtmlTextWriter.DefaultTabString que define la sangría de línea predeterminada utilizada por el escritor de texto XHTML. 125 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 En este ejemplo de código también se muestra la forma de reemplazar los métodos OnAttributeRender y OnStyleAttributeRender para filtrar por el tamaño de texto y el estilo de color, respectivamente. Además, reemplaza los métodos BeginRender y EndRender para escribir una cadena de texto antes y después de que se haya representado un control. using using using using using using using System; System.IO; System.Web; System.Security.Permissions; System.Web.UI; System.Web.UI.Adapters; System.Web.UI.WebControls.Adapters; namespace Samples.AspNet.CS { // Create a class that inherits from XhtmlTextWriter. [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] public class CustomXhtmlTextWriter : XhtmlTextWriter { // Create two constructors, following // the pattern for implementing a // TextWriter constructor. public CustomXhtmlTextWriter(TextWriter writer) : this(writer, DefaultTabString) { } public CustomXhtmlTextWriter(TextWriter writer, string tabString) : base(writer, tabString) { } // Override the OnAttributeRender method to // allow this text writer to render only eight-point // text size. protected override bool OnAttributeRender(string name, string value, HtmlTextWriterAttribute key) { if (key == HtmlTextWriterAttribute.Size) { if (String.Compare(value, "8pt") == 0) { return true; } else { return false; } } else { return base.OnAttributeRender(name, value, key); } } // Override the OnStyleAttributeRender // method to prevent this text writer // from rendering purple text. protected override bool OnStyleAttributeRender(string name, string value, HtmlTextWriterStyle key) { 126 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 } if (key == HtmlTextWriterStyle.Color) { if (String.Compare(value, "purple") == 0) { return false; } else { return true; } } else { return base.OnStyleAttributeRender(name, value, key); } // Override the BeginRender method to write a // message and call the WriteBreak method // before a control is rendered. override public void BeginRender() { this.Write("A control is about to render."); this.WriteBreak(); } // Override the EndRender method to // write a string immediately after // a control has rendered. override public void EndRender() { this.Write("A control just rendered."); } } } En el ejemplo de código siguiente se muestra la forma de crear un control Label personalizado denominado TestLabel y un adaptador personalizado denominado XhtmlTestLabelAdapter, que representa el contenido del control en XHTML. using using using using using using System; System.Web; System.Web.UI; System.Web.UI.Adapters; System.Web.UI.WebControls; System.Web.UI.WebControls.Adapters; namespace AspNet.Samples { // Create a simple class that inherits // from the Label class. public class TestLabel : Label { private String _textValue; // Override the Text property. public override string Text { get { return (string)ViewState["Text"]; } set { ViewState["Text"] = value; } } } 127 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 public class XhtmlTestLabelAdapter : WebControlAdapter { // Create a control property that accesses the // methods and properties of the control. protected TestLabel Control { get { return (TestLabel)base.Control; } } protected override void Render(HtmlTextWriter writer) { // Create an instance of the XhtmlTextWriter class, // named w, and cast the HtmlTextWriter passed // in the writer parameter to w. XhtmlTextWriter w = new XhtmlTextWriter(writer); // Create a string variable, named value, to hold // the control's Text property value. String value = Control.Text; // Create a Boolean variable, named attTest, // to test whether the Style attribute is // valid in the page that the control is // rendered to. Boolean attTest = w.IsValidFormAttribute("style"); // Check whether attTest is true or false. // If true, a style is applied to the XHTML // content. If false, no style is applied. if (attTest) w.EnterStyle(Control.ControlStyle); // Write the Text property value of the control, // a <br> element, and a string. w.Write(value); w.WriteBreak(); w.Write("This control conditionally rendered its styles for XHTML."); // Check whether attTest is true or false. // If true, the XHTML style is closed. // If false, nothing is rendered. if (attTest) w.ExitStyle(Control.ControlStyle); } } } En el ejemplo de código siguiente se muestra la forma de utilizar el control TestLabel personalizado en una página Web ASP.NET. <%@ Page Language="C#" %> <%@ Import Namespace="AspNet.Samples" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd"> <script runat="server"> protected void Page_Load(object sender, EventArgs e) { TestLabel tl = new TestLabel(); tl.ID = "TestLabel1"; 128 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 PlaceHolder1.Controls.Add(tl); } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>XHtmlTextWriter Example</title> </head> <body> <form id="form1" runat="server" > <div> <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder> </div> </form> </body> </html> Para utilizar el control personalizado en el ejemplo de código anterior, se agrega el elemento <controlAdapters> siguiente a uno de los dos archivos indicados a continuación. Se puede agregar al archivo adecuado para todos los equipos en el subdirectorio correspondiente a un explorador concreto, como una subcarpeta del directorio de configuración de .NET Framework. Como alternativa, se puede agregarlo a un archivo de explorador personalizado en el directorio App_Browsers del directorio raíz de la aplicación Web. <controlAdapters> <adapter controlType="AspNet.Samples.TestLabel" adapterType="AspNet.Samples.XhtmlTestLabelAdapter" /> </controlAdapters> App_Browsers Contiene definiciones del explorador (archivos .browser) que ASP.NET utiliza para identificar los exploradores individuales y determinar sus funciones. Los archivos de definición del explorador contienen definiciones para exploradores individuales. En tiempo de ejecución, ASP.NET utiliza la información del encabezado de la solicitud para determinar qué tipo de explorador ha realizado la solicitud. A continuación, ASP.NET utiliza archivos .browser para determinar las capacidades del explorador. Los adaptadores de control ASP.NET pueden utilizar esta información para adaptar el comportamiento de un control de servidor web ASP.NET dependiendo del tipo de dispositivo. Por ejemplo, un control de servidor podría generar HTML diferente para un explorador gráfico como Internet Explorer que para un dispositivo móvil. <browsers> <browser id="browser name" parentID="parent browser name" refID="reference ID"> <identification> <userAgent match="regular expression" nonMatch="regular expression" /> <header match="regular expression" name="header name" nonMatch="regular expression" /> <capability match="regular expression" name="capability name" nonMatch="regular expression" /> </identification> <capture> <userAgent match="regular expression" /> <header match="regular expression" name="header name" /> <capability match="regular expression" 129 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 name="capability name" /> </capture> <capabilities> <capability name="capability name" value="capability value" /> </capabilities> <controlAdapters markupTextWriterType="type name"> <adapter adapterType="name of adapter class" controlType="name of control class" /> </controlAdapters> <sampleHeaders> <header name="header name" value="header value" /> </sampleHeaders> </browser> <gateway id="gateway ID" parentID="parent browser ID"> <!-- Same child elements as for <browser>. <identification></identification> <capture></capture> <capabilities></capabilities> <controlAdapters></controlAdapters> <sampleHeaders></sampleHeaders> --> </gateway> <defaultBrowser id="Default" parentID="parent browser ID" refID="reference ID" > <!-- Same child elements as for <browser>. <identification></identification> <capture></capture> <capabilities></capabilities> <controlAdapters></controlAdapters> <sampleHeaders></sampleHeaders> --> </defaultBrowser> </browsers> 33 PERSONALIZAR EL DISEÑO Y APARIENCIA DE UNA PÁGINA WEB: CSS, temas y funciones, páginas principales y elementos Web, App_Themes, StyleSheetTheme App_Themes Contiene una colección de archivos (archivos .skin y .css, así como archivos de imagen y recursos genéricos) que definen el aspecto de las páginas Web y controles ASP.NET. TEMAS Y MÁSCARAS DE ASP.NET Un tema es un conjunto de valores de propiedad que permiten definir la apariencia de las páginas y de los controles y, a continuación, aplicar esa apariencia de manera coherente a las páginas de una aplicación Web, en toda una aplicación Web o en todas las aplicaciones Web de un servidor. Máscaras de temas y control Los temas están formados por un conjunto de elementos: máscaras, hojas de estilos en cascada (CSS), imágenes y otros recursos. Como mínimo, un tema contendrá máscaras. Los temas se definen en directorios especiales en un sitio Web o un servidor web. Máscaras Un archivo de máscara tiene la extensión de nombre de archivo .skin y contiene los valores de propiedades para los controles individuales como Button, Label, TextBox o Calendar. La configuración de las máscaras de control se parece al propio marcado del control, pero sólo contiene las propiedades que se desee establecer como parte del tema. Por ejemplo, lo siguiente es una máscara de control Button: <asp:button runat="server" BackColor="lightblue" ForeColor="black" /> 130 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Los archivos .skin se crean en la carpeta Theme. Un archivo .skin puede contener una o más máscaras de control para uno o más tipos de control. Es posible definir un archivo de máscaras independiente para cada control o definir todas las máscaras para un tema en un archivo único. Hay dos tipos de máscaras de control, máscaras predeterminadas y máscaras con nombre: Una máscara predeterminada se aplica automáticamente a todos los controles del mismo tipo cuando un tema se aplica a una página. Una máscara de control es predeterminada si no tiene un atributo SkinID. Por ejemplo, si se crea una máscara predeterminada para un control Calendar, la máscara de control se aplicará a todos los controles Calendar de las páginas en las que se utilice el tema. (Las máscaras predeterminadas coinciden exactamente atendiendo al tipo de control, de modo que una máscara de control Button se aplica a todos los controles Button pero no a los controles LinkButton ni a los derivados del objeto Button). Una máscara con nombre es una máscara de controles con un conjunto de propiedades SkinID. Las máscaras con nombre no se aplican automáticamente a todos los controles según el tipo. En su lugar, una máscara con nombre se aplica explícitamente a un control estableciendo la propiedad SkinID del control. Al crear máscaras con nombre, se pueden configurar diferentes máscaras para distintas instancias del mismo control en una aplicación. Hojas de estilos en cascada Un tema también puede incluir una hoja de estilos en cascada (archivo .css). Cuando se coloca un archivo .css en la carpeta de temas, la hoja de estilos se aplica automáticamente como parte del tema. La hoja de estilos se define utilizando la extensión de nombre de archivo .css en la carpeta de tema. Gráficos del tema y otros recursos Los temas también pueden incluir gráficos y otros recursos, como archivos de script o archivos de sonido. Por ejemplo, la parte de un tema de página podría incluir una máscara para un control TreeView. Como parte del tema, se pueden incluir los gráficos utilizados con el fin de representar los botones para expandir y contraer. Normalmente, los archivos de recursos del tema están en la misma carpeta que los archivos de máscara de dicho tema, pero pueden estar en cualquier parte de la aplicación Web, por ejemplo, en una subcarpeta de la carpeta de temas. Para hacer referencia a un archivo de recursos en una subcarpeta de la carpeta de temas, se utiliza una ruta de acceso como la que se muestra en esta máscara de control Image: <asp:Image runat="server" ImageUrl="ThemeSubfolder/filename.ext" /> También se puede almacenar sus archivos de recursos fuera de la carpeta de temas. Si utiliza la sintaxis de la tilde (~) para hacer referencia a los archivos de recursos, la aplicación Web encontrará automáticamente las imágenes. Por ejemplo, si se coloca los recursos de un tema en una subcarpeta de la aplicación, puede utilizar rutas de acceso como ~/Subcarpeta/nombreArchivo.ext para hacer referencia a los archivos de recursos, como en el siguiente ejemplo. <asp:Image runat="server" ImageUrl="~/AppSubfolder/filename.ext" /> Ámbito de los temas Se puede definir temas para una aplicación Web única o como temas globales que pueden utilizar todas las aplicaciones en un servidor web. Una vez definido un tema, se puede colocar en páginas individuales utilizando el atributo Theme o StyleSheetTheme de la directiva @ Page, o se puede aplicar a todas las páginas de una aplicación configurando el elemento <pages> en el archivo de configuración de la aplicación. Si el elemento <pages> se define en el archivo Machine.config, el tema se aplicará a todas las páginas de las aplicaciones web en el servidor. Temas de página Un tema de página corresponde a una carpeta de temas con máscaras de control, hojas de estilos, archivos de gráficos y otros recursos creados como una subcarpeta de la carpeta \App_Themes en el sitio Web. Cada tema constituye una subcarpeta diferente con respecto a la carpeta \App_Themes. En el siguiente ejemplo de código se muestra un tema de página típico que define dos temas denominados BlueTheme y PinkTheme. MyWebSite App_Themes 131 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 BlueTheme Controls.skin BlueTheme.css PinkTheme Controls.skin PinkTheme.css Temas globales Un tema global es un tema que puede aplicar a todos los sitios Web en un servidor. Los temas globales permiten definir una apariencia de conjunto para un dominio cuando se mantienen varios sitios Web en el mismo servidor. Los temas globales se parecen a los de página en que ambos tipos incluyen valores de propiedades, la configuración de las hojas de estilos y gráficos. Sin embargo, los temas globales se almacenan en una carpeta denominada Themes que es global al servidor web. Cualquier sitio Web del servidor y cualquier página de cualquier sitio Web pueden hacer referencia a un tema global. Prioridad en la configuración de temas Se puede especificar la prioridad que tiene la configuración del tema sobre la configuración regional del control especificando cómo se aplica el tema. Si se establece la propiedad de una página Theme, los valores de control en el tema y la página se combinan para formar la configuración final para el control. Si la configuración del control se define tanto en el control como en el tema, la configuración del control del tema reemplaza cualquier configuración de la página en el control. Esta estrategia hace posible que el tema pueda crear una apariencia coherente a lo largo de las páginas, incluso si los controles de las páginas ya tuvieran valores de propiedades individuales. Por ejemplo, esto permite aplicar un tema a una página que se creó en una versión anterior de ASP.NET. Asimismo, es posible aplicar un tema como tema de la hoja de estilos estableciendo la propiedad StyleSheetTheme de la página. En este caso, la configuración de la página local tiene prioridad sobre aquellos definidos en el tema cuando la configuración se define en ambos lugares. Éste es el modelo utilizado en las hojas de estilos en cascada. Se podría aplicar un tema como tema de la hoja de estilos si se desea poder establecer las propiedades de controles individuales en la página mientras se sigue aplicando un tema para lograr una apariencia de conjunto. Los elementos de temas globales no pueden reemplazarse parcialmente por elementos de temas de nivel de aplicación. Si crea un tema de nivel de aplicación con el mismo nombre que un tema global, los elementos de tema de nivel de aplicación no reemplazarán los elementos del tema global. Propiedades que se pueden definir mediante temas Como regla general, se pueden usar los temas para definir las propiedades relacionadas con la apariencia de una página o de un control o el contenido estático. Sólo se pueden establecer esas propiedades que tienen un atributo ThemeableAttribute establecidas como true en la clase de control. Las propiedades que especifican explícitamente el comportamiento de los controles en lugar de su apariencia no aceptan valores de tema. Por ejemplo, no se puede configurar la propiedad CommandName de un control Button mediante un tema. De manera similar, no se puede utilizar un tema para configurar la propiedad AllowPaging o DataSource de un control GridView. Tener en cuenta que no puede utilizar generadores de expresiones, que generan expresiones de código para asignarlas a una página en tiempo de compilación, en temas o máscaras. Temas frente a Hojas de estilos en cascada Los temas son similares a las hojas de estilos en cascada en cuanto a que tanto los temas como las hojas de estilos definen una serie de atributos comunes que se pueden aplicar a cualquier página. Sin embargo, los temas se diferencian de las hojas de estilos en los siguientes puntos: 132 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Los temas pueden definir muchas propiedades de un control o de una página, y no sólo las propiedades de un estilo. Por ejemplo, los temas permiten especificar los gráficos de un control TreeView, el diseño de plantilla de un control GridView, etcétera. Los temas pueden incluir gráficos. Los temas no se colocan en cascada de la misma manera que las hojas de estilos. De forma predeterminada, cualquier valor de propiedad definido en un tema al que se haga referencia en la propiedad Theme de una página reemplazará los valores de las propiedades establecidos mediante declaración, a menos que aplique explícitamente el tema mediante la propiedad StyleSheetTheme. Sólo se puede aplicar un tema a cada página. No puede aplicar varios temas a una página, a diferencia de las hojas de estilos que sí se pueden aplicar varias. Consideraciones de seguridad Los temas pueden causar problemas de seguridad cuando se utilizan en el sitio Web. Se pueden utilizar temas malintencionados para: Modificar el comportamiento de un control de forma que no se comporte según lo previsto. Insertar script de cliente, lo que puede suponer un riesgo de scripting entre sitios. Modificar la validación. Divulgar información confidencial. Las formas de mitigar estas amenazas comunes son las siguientes: Proteger los directorios de temas globales y de aplicación con una configuración de control de acceso apropiada. Sólo los usuarios de confianza deben poder escribir archivos en los directorios de temas. No utilizar temas de un origen que no sea de confianza. Examinar todos los temas que no provengan de su organización por si contienen código malintencionado antes de utilizarlos en su sitio Web. No exponer el nombre del tema en los datos de una consulta. Los usuarios malintencionados podrían utilizar esta información para usar temas que el programador no conoce y, de ese modo, divulgar información confidencial. CONTROLES DE SERVIDOR WEB ASP.NET Y ESTILOS DE CSS Se puede controlar el aspecto de los controles de servidor de ASP.NET estableciendo varias propiedades de aspecto como ForeColor, BackColor, Height y Width. Además, algunos controles admiten objetos de estilo que exponen una configuración relacionada con el estilo adicional. Nota: Las páginas Web ASP.NET funcionan como páginas HTML en tiempo de ejecución. Por consiguiente, se puede utilizar hojas de estilo en cascada (CSS) para establecer la apariencia de cualquier elemento en la página que no sea los controles de servidor Web. Además, se puede definir temas de ASP.NET que incluyen la configuración de hojas de estilos en cascada y, a continuación, aplicar los temas a las páginas o al sitio. Las secciones siguientes proporcionan información sobre cómo establecer estilos directamente, incluso cómo trabajar con estilos tanto en tiempo de diseño como mediante programación. Representación de propiedades de apariencia en el explorador Cuando se ejecuta la página, las propiedades de apariencia se representan según las capacidades del explorador del usuario. Si el explorador del usuario admite hojas de estilos en cascada (CSS), las propiedades de apariencia se representan como atributos de estilo de los elementos HTML que componen el control. Por ejemplo, si se define un control de servidor Web HyperLink y establece su propiedad ForeColor en Red, su propiedad Bold en true y su propiedad Size en xx-small, el control se representa como el que se incluye a continuación si el explorador del usuario admite hojas de estilos: <a id="hyperlink1" style="color: red; font-size: xx-small; font-weight: bold;">HyperLink</a> Por otro lado, si el explorador del usuario no admite estilos, el control se representa por otros medios, como un elemento <font>. A continuación se muestra la representación del ejemplo anterior, pero para un explorador que no admite estilos: <a id="a1"><b><font color="red" size="1">HyperLink</font></b></a> Otros ejemplos de propiedades que se representan de forma diferente dependiendo del explorador son BorderWidth y BorderColor. 133 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Algunas propiedades de apariencia, como BorderStyle no se puede representar sin utilizar estilos. Estas propiedades se omiten por consiguiente en exploradores que no admiten estilos. Objetos de estilo del control Además de las propiedades de apariencia como ForeColor y BackColor, los controles exponen uno o varios objetos de estilo que encapsulan propiedades de apariencia adicionales. Un ejemplo lo constituye la propiedad del estilo Font, que expone un objeto de tipo FontInfo que contiene propiedades individuales pertenecientes a la fuente, como Size, Name y Bold. Algunos controles exponen objetos de estilo que puede utilizar para establecer la apariencia de partes específicas del control. Por ejemplo, el control Calendar de servidor Web contiene objetos de estilo como DayStyle (días individuales), SelectedDayStyle (un día, una semana o un mes seleccionado por el usuario) y WeekendDayStyle. Al utilizar, por ejemplo, el objeto de estilo SelectedDayStyle, se pueden establecer las propiedades BackColor y ForeColor del día seleccionado por el usuario. La mayor parte de los objetos de estilo son de tipo Style o TableItemStyle porque establecen los atributos de celdas de tabla. La propiedad Font es de tipo FontInfo. Prioridad y herencia de los objetos de estilo En controles complejos, los objetos de estilo a menudo heredan características de otros objetos de estilo. Por ejemplo, en el control Calendar, el objeto SelectedDayStyle está basado en el objeto DayStyle. Si no establece explícitamente ninguna propiedad para SelectedDayStyle, hereda las características del objeto DayStyle. Esta herencia significa que las propiedades del objeto de estilo que ha establecido tienen un orden de prioridad. Por ejemplo, la siguiente lista muestra el orden de las propiedades del objeto de estilo para el control Calendar, con la mayor prioridad dada a la configuración del último objeto de la lista. 1. Propiedades de apariencia del control Calendar base. 2. Objeto de estilo DayStyle. 3. Objeto de estilo WeekendDayStyle. 4. Objeto de estilo OtherMonthDayStyle. 5. Objeto de estilo TodayDayStyle. 6. Objeto de estilo SelectedDayStyle. Pueden surgir dificultades con los estilos cuando éstos se dividen entre un elemento de contenedor y un elemento de texto. Por ejemplo, suponga que tiene una hoja de estilos para un control, y desea aplicar las propiedades de estilo de texto a un vínculo y aplicar el resto del estilo a un contenedor. Esto es posible si establece los estilos mediante las propiedades de estilo del control, como MenuItemStyle para un control de menú o TodayDayStyle para un control de calendario. Pero es más difícil si se utilizan los estilos definidos por una propiedad CssClass, porque ASP.NET no tiene forma de conocer el contenido de la clase en el servidor. ASP.NET aplica los estilos definidos en la propiedad CssClass a los elementos de texto y de contenedor, y agrega un estilo en línea para suprimir los efectos de esta aplicación doble (bordes dobles, multiplicación de las fuentes proporcionales, etc.). La mejor manera de aplicar estilo a un control es utilizar las propiedades de estilo definidas por el control y usar una hoja de estilos o estilos en línea para realizar pequeños ajustes en los distintos elementos, si es necesario. Para reemplazar un estilo definido por las propiedades de estilo de un control, utilice la regla de CSS importante en un hoja de estilos o en estilos en línea. En el ejemplo de código siguiente se utiliza la propiedad CssClass en el elemento hovernodestyle. Esta clase se define dos veces como myclass y como a.myclass:visited para reemplazar la definición de a:visited. <%@ Page Language="C#" %> <html> <head runat="server"> <asp:sitemapdatasource id="SiteMapSource" runat="server" /> <style type="text/css"> a:visited { 134 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 color: #000066 } myclass, a.myclass:visited { color: #FF0000 } </style> </head> <body> <form runat="server"> <a href="http://www.Contoso.com">Contoso</a> <asp:treeview id="treeview1" runat="server" initialexpanddepth="1" datasourceid="SiteMapSource" forecolor="#444444" font-names="Verdana" font-size="0.8em"> <nodestyle font-bold="true" /> <hovernodestyle cssclass=myclass /> </asp:treeview> </form> </body> </html> Si se utiliza hojas de estilos en cascada (CSS) para personalizar el aspecto de un control, emplear estilos en línea o un archivo CSS independiente, pero no ambos. El uso de estilos en línea y un archivo CSS independiente puede producir resultados imprevistos. Controlar clases y estilos CSS directamente Además de las propiedades de apariencia y objetos de estilo, los controles exponen dos propiedades que permiten manipular estilos CSS de una forma más directa: CssClass y Style. La propiedad CssClass permite asignar una clase de hoja de estilos al control. La propiedad Style permite establecer una cadena de atributos de estilo para que se escriba tal cual en el control. El uso de la propiedad Style permite establecer atributos de estilo que no se exponen a través de otras propiedades. La propiedad Style expone una colección a cuyos métodos, como Add y Remove, puede llamar para establecer directamente los estilos. La configuración realizada en la propiedad Style no se refleja en la propiedad de apariencia individual correspondiente. Por ejemplo, si establece una cadena background-color:red en la propiedad Style, la propiedad BackColor tampoco se establece en rojo, aunque el control se represente con un fondo rojo. Si establece tanto propiedades de apariencia como la propiedad Style, las propiedades de apariencia individuales tienen precedencia sobre la propiedad Style. 135 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 34 TRABAJAR CON OBJETOS INTRÍNSECOS DE ASP.NET: Request, Server, Application, Session, Response, HttpContext Espacio de nombres System.Web El espacio de nombres System.Web ofrece clase en intergaces que habilitan la comunicación entre el servidor y el navegador. Este espacio de nombre incluye la clase HttpRequest, la cual contiene toda la información de un request HTTP; la clase Httpresponse la cual controla la salida HTTP al cliente; y la clase HttpServerUtility la cual prove acceso a los utilitarios del lado del servidor y los procesos. System.Web también incluye clases para la manipulación de “cookies”, transferencia de arhivos, información de excepciones y control del cache. Clase HttpRequest Permite a ASP.NET leer los valores HTTP enviados por un cliente durante una solicitud Web. Los métodos y propiedades de la clase HttpRequest se exponen a través de las propiedades Request de las clases HttpApplication, HttpContext, Page y UserControl. Clase HttpServerUtility Proporciona métodos auxiliares para procesar las solicitudes Web. Los métodos y las propiedades de la clase HttpServerUtility se exponen a través del objeto intrínseco Server proporcionado por ASP.NET. La propiedad Server proporciona acceso mediante programación a las propiedades y los métodos de la clase HttpServerUtility. Como las páginas ASP.NET contienen una referencia predeterminada al espacio de nombres System.Web (que contiene la clase HttpContext), se puede hacer referencia a los miembros de HttpContext en una página .aspx sin la referencia de clase completa a HttpContext. Por ejemplo, se puede utilizar simplemente Server.CreateObject("MyCOMComponent") para crear una instancia de un objeto COM en el servidor. No obstante, si desea utilizar los miembros de HttpServerUtility desde un módulo de código subyacente ASP.NET, debe incluir en el módulo una referencia al espacio de nombres System.Web y, además, una referencia completa al contexto de solicitud/respuesta que esté activo en ese momento y a la clase de System.Web a utilizar. Clase HttpApplication Define los métodos, las propiedades y los eventos comunes a todos los objetos de aplicación incluidos en una aplicación ASP.NET. Esta clase es la clase base para las aplicaciones definidas por el usuario en el archivo Global.asax. Las instancias de la clase HttpApplication se crean en la infraestructura ASP.NET; no las crea directamente el usuario. Una única instancia de la clase HttpApplication puede procesar muchas solicitudes durante su vida útil, pero sólo una cada vez. Por tanto, se pueden utilizar variables miembro para almacenar datos para cada solicitud. Una aplicación ejecuta los eventos administrados por módulos o código de usuario definido en el archivo Global.asax en el orden siguiente: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. BeginRequest AuthenticateRequest PostAuthenticateRequest AuthorizeRequest PostAuthorizeRequest ResolveRequestCache PostResolveRequestCache Después del evento PostResolveRequestCache y antes del evento PostMapRequestHandler, se crea un controlador de eventos (una página que corresponde a la dirección URL de la solicitud) PostMapRequestHandler AcquireRequestState PostAcquireRequestState PreRequestHandlerExecute PostRequestHandlerExecute ReleaseRequestState PostReleaseRequestState Después del evento PostReleaseRequestState, los filtros de respuesta, si los hay, filtran el resultado. 136 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 15. UpdateRequestCache 16. PostUpdateRequestCache 17. EndRequest Propiedad Page.Session Obtiene el objeto Session actual proporcionado por ASP.NET. Esta propiedad proporciona información sobre la sesión de solicitud actual. Se mantiene un objeto Session para cada usuario que solicita una página o un documento de una aplicación ASP.NET. Las variables almacenadas en el objeto Session no se descartan cuando el usuario se desplaza de una página a otra en la aplicación; en su lugar, estas variables persisten siempre y cuando el usuario esté obteniendo acceso a las páginas de la aplicación. Clase HttpResponse Encapsula la información de la respuesta HTTP de una operación ASP.NET. Los métodos y propiedades de la clase HttpResponse se exponen a través de la propiedad Response de las clases HttpApplication, HttpContext, Page y UserControl. Clase HttpContext Encapsula toda la información específica de HTTP acerca de una solicitud HTTP individual. A las clases que heredan las interfaces IHttpModule y IHttpHandler se les proporciona una referencia a un objeto HttpContext para la actual solicitud HTTP. El objeto proporciona acceso a las propiedades Request, Response y Server intrínsecas de la solicitud. 35 IMPLEMENTAR LA GLOBALIZACIÓN Y ACCESIBILIDAD: archivos de recursos, configuración de cultura, RegionInfo, App_GlobalResources, App_LocalResources, TabIndex, AlternateText , GenerateEmptyAlternateText, AccessKey, Label.AssociatedControlID INFORMACIÓN GENERAL SOBRE LA GLOBALIZACIÓN Y LA LOCALIZACIÓN En el pasado, el término localización se refería a menudo a un proceso que comenzaba después de que un programador de aplicaciones compilase los archivos fuente en el idioma original. Entonces, otro equipo iniciaba el proceso de modificación de los archivos fuente para que pudieran usarse en otro idioma. El idioma original podía ser, por ejemplo, el inglés; y el segundo idioma, el alemán. Este enfoque, sin embargo, es prohibitivo y provoca incoherencias entre versiones. Incluso ha propiciado que algunos clientes se decidieran a comprar la versión original del programa para no tener que esperar la durante varios meses la llegada de la versión localizada. Un modelo más rentable y funcional divide el proceso de desarrollo de aplicaciones de uso internacional en tres partes bien diferenciadas: globalización, localizabilidad y localización. Las principales ventajas de diseñar e implementar aplicaciones que tengan en cuenta y se adapten a las convenciones regionales, a datos en diversos idiomas y a formatos diferentes son: • Se puede lanzar la aplicación al mercado más rápidamente. No se necesita desarrollo adicional para localizar una aplicación una vez que la versión original está completa. • Se aprovechan los recursos de manera más eficaz. Al convertir la adaptación a criterios internacionales en una parte del proceso de desarrollo original, hacen falta menos desarrollo y menos recursos de comprobación que si agregara esa opción una vez iniciado el trabajo. Es más, si agrega la adaptación a criterios internacionales cuando la aplicación esté concluida, es posible que la haga menos estable, y cree problemas que podría haber resuelto al principio. • La aplicación es más fácil de mantener. Si genera la versión localizada de la aplicación desde el mismo conjunto de fuentes que la versión original, sólo algunos módulos aislados necesitarán localización. Por lo tanto, el código será más fácil y barato de mantener si incluye las características de uso internacional. La clave de este aspecto del diseño de software radica en usar archivos de recursos para las versiones localizadas de la aplicación. La globalización es el proceso de diseño y desarrollo de un producto de software que pueda funcionar con diversas culturas o configuraciones regionales. Este proceso requiere: 137 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 • Identificar las culturas o configuraciones regionales que deberá admitir el software • Diseñar características válidas para las diferentes culturas o configuraciones regionales • Escribir código que funcione igualmente bien en cada una de las culturas o configuraciones regionales admitidas En otras palabras, la globalización permite la entrada, presentación y salida de un conjunto definido de secuencias de comandos de idioma perteneciente a una determinada área geográfica. La mejor manera de globalizar estas funciones es utilizar el concepto de culturas o configuraciones regionales. Una cultura o configuración regional es un conjunto de reglas y otro de datos, específicos de un área geográfica e idioma determinados. Estas reglas y datos incluyen información acerca de: • Clasificación de caracteres • Formato de fecha y hora • Convenciones numéricas, monetarias, de pesos y de medidas • Reglas de ordenación CONCEPTOS COMUNES DE RECURSOS La mayor parte de los aspectos de programación en .NET Framework son los mismos para todos los lenguajes compatibles, ya que sus compiladores generan código MSIL (Microsoft Intermediate Language, Lenguaje intermedio de Microsoft) administrado y autodescriptivo. El código MSIL administrado se ejecuta con Common Language Runtime, que proporciona integración entre varios lenguajes, administración de memoria automática, control de excepciones entre lenguajes, mayor seguridad y un modelo simplificado para la interacción entre componentes. Además del motor de tiempo de ejecución, .NET Framework incluye la biblioteca de clases de .NET Framework, a la que también se puede tener acceso desde cualquier lenguaje compatible con .NET. Varios aspectos de este proceso de desarrollo común son particularmente importantes al crear aplicaciones que utilizan recursos. Unidades de creación Las bibliotecas de clases de .NET Framework que se creen también se organizan en espacios de nombres jerárquicos y se almacenan en archivos ejecutables portátiles (PE), normalmente, archivos DLL y EXE. Puede haber varios espacios de nombres, incluso anidados, en un solo archivo PE. Además, un espacio de nombres puede dividirse en varios archivos PE. Se combinan uno o varios archivos PE (y posiblemente otros tipos de archivos, como pueden ser recursos) para crear un ensamblado, que es una unidad física que se puede implementar, volver a utilizar y a la que se puede asignar un número de versión. El motor de tiempo de ejecución utiliza los ensamblados para localizar y enlazar a los tipos a los que se hace referencia. Los recursos también se pueden enlazar en ensamblados, se pueden empaquetar por separado con varios formatos diferentes o incluso se pueden utilizar como archivos individuales, por ejemplo, como imágenes JPEG. La información relativa a lo que contiene un ensamblado, incluidas las clases y recursos, está contenida en el manifiesto del ensamblado. Referencias culturales En .NET Framework, una referencia cultural es el idioma del usuario combinado, opcionalmente, con la ubicación del propio usuario. Al especificar una referencia cultural, es posible utilizar un conjunto de preferencias comunes para determinada información, como cadenas, formato de fechas y formato de números, que corresponde a las convenciones de idioma y ubicación del usuario. La ubicación puede ser un país o una región; esto último puede ser el término geopolíticamente correcto en una ubicación donde un país no se reconoce oficialmente. El idioma y la ubicación se pueden especificar mediante códigos definidos por RFC 1766 de Internet, "Etiquetas para la identificación de idiomas". Los propios códigos reales se definen mediante dos estándares ISO: ISO 639, "Códigos para la representación de nombres de idiomas", e ISO 3166, "Códigos para la representación de nombres de países". Vea el tema "Etiquetas de idioma y de país o región" en el Apéndice A: Información adicional de recursos para obtener información de referencia acerca de estos estándares. Se puede tener acceso a las preferencias detalladas de referencias culturales mediante las instancias de la clase CultureInfo, a las que, a su vez, se tiene acceso mediante etiquetas de referencias culturales. Las etiquetas de referencias culturales utilizan el formato principal[-secundario], donde la etiqueta principal es el idioma y la etiqueta secundaria opcional es el código de país o región. Por convención, la etiqueta de idioma está compuesta de dos letras en minúsculas y la etiqueta de país o región está compuesta de dos letras en mayúsculas. La tabla siguiente contiene ejemplos de referencias de etiquetas culturales. 138 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 de Alemán de-AT Alemán de Austria de-CH Alemán de Suiza en Inglés en-US Inglés de Estados Unidos en-AU Inglés de Australia en-CA Inglés de Canadá fr Francés sp Español En .NET Framework, las etiquetas de dos letras indican referencias culturales neutras, solamente de idioma, como de para alemán. Las etiquetas de cuatro letras indican referencias culturales específicas, tales como fr-CA para el francés que se habla en Canadá. En la mayor parte de las situaciones, la interfaz de usuario se especifica como una referencia cultural específica. Sin embargo, en ciertos casos, como ja-JP para el japonés de Japón, solamente hay una referencia cultural específica. En esta situación, a menudo se utilizan ambas etiquetas indistintamente. Si es necesario que una aplicación pueda establecer una referencia cultural específica, quizás como respuesta a la configuración de un explorador de Internet, la aplicación debe asignar todas las referencias culturales neutras a referencias culturales específicas con el método CreateSpecificCulture Las referencias culturales en .NET Framework ocupan el lugar de la configuración regional de NLS (National Language Support, compatibilidad con el idioma nacional), que utiliza códigos de LCID (Locale Identifier, identificador de configuración regional). La propiedad LCID de la clase CultureInfo proporciona interoperabilidad y facilita la integración con el software basado en NLS. Clases de recursos de .NET La biblioteca de clases de .NET Framework ofrece varias clases para que los programadores puedan trabajar con recursos en sus aplicaciones y herramientas. Clase ResourceManager La clase ResourceManager (del espacio de nombres System.Resources) proporciona un acceso cómodo a recursos de referencias culturales en tiempo de ejecución. Esta clase proporciona una reserva de recursos (normalmente para la referencia cultural neutra) cuando no existe un recurso localizado, permite la serialización de recursos y proporciona el método CreateFileBasedResourceManager para tener acceso a los recursos que no están empaquetados en un ensamblado. Por supuesto, los programadores también pueden derivar clases de ResourceManager al crear soluciones de recursos personalizados. Clase ResourceWriter La clase ResourceWriter (del espacio de nombres System.Resources) escribe recursos en el formato predeterminado del sistema en un archivo o secuencia de salida. Los recursos se especifican como pares de nombre y valor mediante el método AddResource. En los nombres de recursos se distinguen mayúsculas y minúsculas cuando se utilizan para búsquedas, pero ResourceWriter no escribe un nombre de recurso en un archivo de recursos si el nombre varía solamente en las mayúsculas y minúsculas. La clase ResourceWriter proporciona una implementación predeterminada de la interfaz IResourceWriter y el programador la puede reemplazar. Nota Los recursos no se escribirán necesariamente en el mismo orden en que se agregaron con el programa. Clase ResourceReader La clase ResourceReader (del espacio de nombres System.Resources) enumera las secuencias y archivos de recursos, y lee los pares secuenciales de nombre y valor de los recursos. Esta clase proporciona una implementación predeterminada de la interfaz IResourceReader que, como la clase ResourceWriter, el programador puede reemplazar. 139 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Clase ResourceSet La clase ResourceSet (del espacio de nombres System.Resources) almacena todos los recursos localizados para una referencia cultural determinada. Todos los recursos se cargan inmediatamente en la memoria. A diferencia de ResourceManager, ResourceSet no tiene reservas de recursos. Por este motivo, ResourceSet resulta útil principalmente para crear herramientas y utilidades pero no en aplicaciones localizadas. ResourceSet también se puede utilizar para controlar la caché de recursos (por ejemplo, para impedir que se guarden imágenes en caché). Clase CultureInfo La clase CultureInfo (del espacio de nombres System.Globalization) contiene un conjunto de información sobre las preferencias del usuario en función del idioma, idioma secundario, país o región, y convenciones culturales del usuario. Esta clase se utiliza para dar formato a fechas, horas y números, para ordenar cadenas y para determinar la elección del idioma del texto. Clase RegionInfo La clase RegionInfo (del espacio de nombres System.Globalization) se utiliza para determinar la unidad de medida y asignar códigos de región a los nombres de regiones. Método Assembly.GetManifestResourceStream El método Assembly.GetManifestResourceStream (del espacio de nombres System.Reflection) carga directamente en una secuencia los datos de recursos del manifiesto. Resulta particularmente útil cuando los recursos están almacenados con formatos personalizados, que ResourceManager no podría entender de forma nativa. Nota Para usar el método Assembly.GetManifestResourceStream, los recursos deben encontrarse en un ensamblado. Propiedad Thread.CurrentUICulture La propiedad Thread.CurrentUICulture (del espacio de nombres System.Threading) es útil cuando hay que determinar la referencia cultural actual o, lo que es más importante, para establecer la referencia cultural y emular la ejecución en una versión localizada de Windows diferente. Esto es necesario ya que el Panel de control no puede mostrar varios LCID de interfaz en una versión de Windows 2000 que carezca de una interfaz de usuario multilenguaje. En cambio, se puede establecer la referencia cultural mediante programa en tiempo de ejecución o mediante subprocesos. Implementación En el caso más sencillo, un archivo independiente y ejecutable de .NET Framework se puede ejecutar localmente en cualquier equipo donde esté instalado Common Language Runtime. No hace falta más, no se crean entradas en el Registro, nada puede interrumpir otra aplicación ni hacer que se deje de ejecutar y con eliminar el archivo (si se copió localmente) basta para quitar la aplicación sin dejar huellas en el equipo. Las aplicaciones que se ejecutan desde una dirección URL que representa un sitio Web se comportan de forma ligeramente distinta. En estos casos, los ensamblados se instalan en la caché de descarga y después se borran automáticamente. Todas las demás aplicaciones, incluidas las de una dirección URL que representa un archivo, se ejecutan a partir del código fuente y no se guardan en la caché del equipo local. Distribución Por supuesto, la mayor parte de las aplicaciones de cliente se empaquetarán en un formato de distribución común (por ejemplo, en un archivo .cab o .msi) y muchas se instalarán mediante mecanismos de distribución de aplicaciones como Windows 2000 IntelliMirror o Microsoft Systems Management Server (SMS), que utilizan la tecnología Microsoft Installer. CÓMO: CREAR ARCHIVOS DE RECURSOS PARA SITIOS WEB ASP.NET Un archivo de recursos es un archivo XML que puede contener cadenas y otros recursos, como rutas de acceso al archivo de imagen. Estos archivos normalmente se utilizan para almacenar cadenas de la interfaz de usuario que se deben traducir a otros idiomas. Esto se debe a que puede crear un archivo de recursos independiente para cada idioma al que desee traducir una página Web. Los archivos de recursos globales están disponibles en cualquier página o componente del sitio Web. Los archivos de recursos locales se asocian a una sola página Web, a un control de usuario o a una página maestra y contienen los recursos sólo de esa página. 140 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 En Visual Web Developer, puede utilizar el editor de recursos administrados para crear los archivos de recursos globales o locales. En los archivos de recursos locales, también puede generar recursos neutros para la referencia cultural directamente desde una página Web del diseñador. Crear recursos manualmente Para crear un archivo de recursos manualmente 1. Asegurarse de que el sitio Web tiene una carpeta en la que almacenar el archivo de recursos mediante una de las siguientes acciones: Si se está creando un archivo de recursos global, debe tener una carpeta denominada App_GlobalResources. Para crear la carpeta, en Explorador de soluciones, clic con el botón secundario del mouse en el nombre del sitio Web, clic en Agregar carpeta y, a continuación, en Carpeta App_GlobalResources. Sólo puede haber una de estas carpetas en una aplicación y debe estar ubicada en la raíz de la aplicación. Si se está creando un archivo de recursos local, debe tener una carpeta denominada App_LocalResources. Para crear la carpeta, en Explorador de soluciones, clic con el botón secundario del mouse en el nombre del sitio Web, clic en Agregar carpeta y, a continuación, en carpeta App_LocalResources. Puede haber muchas carpetas de este tipo en una aplicación y pueden estar ubicadas en cualquier nivel de la misma. 2. Para crear un archivo de recursos, clic con el botón secundario del mouse en las carpetas App_GlobalResources o App_LocalResources y, a continuación, haga clic en Agregar nuevo elemento. Nota: Los archivos de recursos globales deben estar en la carpeta App_GlobalResources. Si se intenta crear un archivo .resx fuera de esta carpeta, Visual Web Developer le indica que se cree en la carpeta. 3. En la opción Plantillas instaladas de Visual Studio del cuadro de diálogo Agregar nuevo elemento, clic en Archivo de recursos de ensamblado. 4. En el cuadro Nombre, escriba un nombre para el archivo de recursos y, a continuación, clic en Agregar. Visual Web Developer abre el archivo en el Editor de recursos administrados. El editor muestra una cuadrícula donde puede escribir nombres (claves), valores y comentarios opcionales. 5. Escribir los nombres y valores de las claves para cada recurso que necesite en la aplicación y, a continuación, guarde el archivo. Nota: No intente incrustar un gráfico directamente en un archivo de recursos porque los controles no leerán la cadena de recurso como archivo de imagen transmitido. Los archivos de recursos representan los gráficos almacenando la dirección URL del gráfico como cadena. 6. Para crear archivos de recursos para idiomas adicionales, copiar el archivo en el Explorador de soluciones o en el Explorador de Windows y, a continuación, cámbiar el nombre mediante uno de los modelos siguientes: Para archivos de recursos globales: nombre.idioma.resx nombre.idioma-referencia cultural.resx Para archivos de recursos locales: nombreDePáginaOControl.extensión.idioma.resx nombreDePáginaOControl.extensión.idioma-referencia cultural.resx Por ejemplo, si se crea un archivo de recursos global denominado WebResources.resx para la traducción al árabe egipcio, asignar al archivo copiado el nombre WebResources.ar-eg.resx. Para crear un archivo de recursos relacionado para la traducción a español sin especificar una referencia cultural, asignar al archivo copiado el nombre WebResources.es.resx. Tener en cuenta que para los archivos de recursos locales, el nombre del archivo de recursos es el nombre de la página o del control, incluyendo la extensión de nombre de archivo, y a continuación la información de idioma y de referencia cultural. 7. Abrir el archivo copiado y traduzca cada valor, sin cambiar los nombres (claves). 8. Repetir los pasos 6 y 7 por cada idioma adicional que desee utilizar. Crear recursos a partir de una página Web La característica siguiente no está disponible con Visual Web Developer Express. Para generar un archivo de recursos local desde una página Web ASP.NET 1. 2. 3. 4. Abrir la página para la que desee crear un archivo de recursos. Cambiar a la vista Diseño. En el menú Herramientas, clic en Generar recurso local. Visual Web Developer crea la carpeta App_LocalResources si aún no existe. Visual Web Developer crea después un archivo de recursos neutros para la referencia cultural de la página actual, que incluye un par de clave-nombre por cada propiedad de control o de página que requiera localización. Finalmente, Visual Web Developer agrega un atributo meta a cada control de servidor web ASP.NET con el fin de configurar el control para utilizar la localización implícita. Escribir los valores de cada recurso que necesite en la aplicación y, a continuación, guardar el archivo. Nota: No se intente incrustar un gráfico directamente en un archivo de recursos porque los controles no leerán la cadena de recurso como 141 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 archivo de imagen transmitido. Los archivos de recursos representan los gráficos almacenando la dirección URL del gráfico como cadena. 5. Si no se muestran los últimos cambios en los recursos, actualizar la vista Diseño; para ello, cambiar a la vista Código fuente y volver a la vista Diseño. 6. Crear archivos de recursos para otros idiomas siguiendo los pasos 6 y 8 del procedimiento anterior. Para generar un archivo de recursos global en Visual Web Developer 1. En el Explorador de soluciones, clic con el botón secundario en el nombre del sitio web, clic en agregar nuevo elemento y, a continuación, en Archivo de recursos. Visual Web Developer le pregunta si desea colocar el archivo en la carpeta App_GlobalResources y se ofrece para crearla. 2. Clic en Sí. 3. Escribir los valores de cada recurso que necesite en la aplicación y, a continuación, guardar el archivo. Nota No intentar incrustar un gráfico directamente en un archivo de recursos porque los controles no leerán la cadena de recurso como archivo de imagen transmitido. Los archivos de recursos representan los gráficos almacenando la dirección URL del gráfico como cadena. 4. Si no se muestran los últimos cambios en los recursos, actualizar la vista Diseño; para ello, cambiar a la vista Código fuente y volver a la vista Diseño. 5. Para crear archivos de recursos para idiomas adicionales, copiar el archivo en el Explorador de soluciones o en el Explorador de Windows y, a continuación, cambiar el nombre mediante uno de los modelos siguientes: nombre.idioma.resx nombre.idioma-referencia cultural.resx Nota En los nombres de archivos de recursos no incluir .aspx para evitar que se produzcan conflictos de nomenclatura. Por ejemplo, la carpeta del recurso no puede contener dos archivos con nombres como resTestPage.resx y resTestPage.aspx.resx. En este caso, la resolución de los nombres de archivo en la compilación crearía un conflicto de nomenclatura, con el consiguiente error en tiempo de compilación CREAR UNA APLICACIÓN WEB ACCESIBLE La creación de páginas Web accesibles permite llegar al máximo número posible de usuarios. Las personas con discapacidades no son los únicos usuarios que apreciarán que las páginas sean accesibles. Los usuarios de exploradores de sólo texto o de software que interpreta el contenido de las páginas Web, podrían depender de las opciones de accesibilidad. El diseño accesible permite que herramientas de automatización tales como los motores de búsqueda, busquen, indicen y manipulen la información de las páginas. Por último, futuras leyes de telecomunicaciones podrían requerir que la información que se distribuye por Internet sea accesible, igual que el software convencional. Las siguientes sugerencias para diseñar páginas Web accesibles proceden del sitio Web de accesibilidad de Microsoft: Proporcionar texto alternativo (ALT) adecuado para todos los gráficos. Hacer un uso correcto de mapas en imágenes. Redactar texto útil en los vínculos. Implantar un buen desplazamiento por el teclado. Proporcionar páginas alternativas que no utilicen marcos. Utilizar las tablas y sus alternativas correctamente. Proporcionar compatibilidad con las opciones de formato del lector de texto. No exijir la utilización de hojas de estilos. Utilizar formatos de archivo que el lector pueda utilizar. Evitar utilizar marquesinas que se desplacen. Proporcionar títulos para la mayoría de los objetos. Si no se puede cumplir los objetivos de accesibilidad, considere la posibilidad de proporcionar páginas Web alternativas que sólo contengan texto. Los controles ASP.NET son compatibles con muchas de las directrices de accesibilidad. Por ejemplo, la indicación del foco del teclado y de elementos de pantalla. SePuede utilizar las propiedades de los controles ASP.NET para ofrecer compatibilidad con otras directrices de accesibilidad, como se muestra a continuación. TabIndex Se utiliza esta propiedad para crear una ruta de desplazamiento razonable a través del formulario. Es importante que los controles que no tienen etiquetas intrínsecas, tales como los cuadros de texto, vayan precedidos de forma inmediata en el orden de tabulación por sus etiquetas asociadas. En casos en que esto no sea posible o deseable, utilizar la propiedad AssociatedControlID de un control Label para asociarlo a un cuadro de texto. 142 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Text Utilizar el elemento HTML para mostrar el método abreviado de teclado de un control. El uso de teclas de acceso contribuye a proporcionar acceso documentado mediante teclado a todas las funciones. (Utilizar la propiedad AccessKey para habilitar un método abreviado de teclado para un control.) Font Size Utilizar etiquetas de encabezado en lugar de tamaños específicos. AlternateText Proporcionar para todas las imágenes texto alternativo que sea significativo para la comprensión del contenido de la página Web. En algunas instancias, es adecuado no establecer texto alternativo para una imagen, como en el caso de imágenes utilizadas para dar formato gráfico. Para representar la propiedad AlternateText de una imagen como vacía, establecer la propiedad GenerateEmptyAlternateText en true para el control Image. AccessKey Utilizar esta propiedad para proporcionar acceso a los controles mediante el teclado. Clase LocalizableAttribute Especifica si se debe traducir una propiedad. Esta clase no se puede heredar. Cuando se genera código para un componente, los miembros que están marcados con el objeto LocalizableAttribute establecido en true tienen sus valores de propiedad guardados en archivos de recursos. Se pueden traducir estos archivos de recursos sin modificar el código. De forma predeterminada, los valores de propiedad de los miembros que no tienen un atributo traducible o que están marcados con el objeto LocalizableAttribute establecido en false persisten en el código si el tipo de datos lo permite. En caso contrario, si el componente principal se establece en Localizable, todas las propiedades persisten en el archivo de recursos. El valor predeterminado es false. Nota Cuando se marca una propiedad con el objeto LocalizableAttribute establecido en true, el valor de este atributo se establece en el miembro constante Yes. En el caso de las propiedades marcadas con el objeto LocalizableAttribute establecido en false, el valor es No. Por tanto, cuando desee comprobar el valor de este atributo en el código, debe especificar el atributo como LocalizableAttribute.Yes o LocalizableAttribute.No. Propiedad AlternateText Image.AlternateText (Propiedad) Obtiene o establece el texto alternativo que se muestra en el control Image cuando no está disponible la imagen. Los exploradores que admiten la característica de información sobre herramientas muestran este texto como una información sobre herramientas. Texto alternativo que se muestra en el control Image cuando no está disponible la imagen. Utilizar esta propiedad para especificar el texto que se ha de mostrar si la imagen especificada en la propiedad ImageUrl no está disponible. En los exploradores que admiten la característica de información sobre herramientas, este texto se muestra también como una información sobre herramientas. 36 IMPLEMENTAR OBJETOS EMPRESARIALES Y CLASES DE UTILIDAD: App_Code , conjuntos externos Carpetas de código compartido en sitios Web ASP.NET Si la aplicación Web incluye código que desea compartir entre las páginas, puede guardarlo en una de las dos carpetas especiales que hay debajo de la raíz de la aplicación Web, Bin y App_Code. Cuando se crean estas carpetas y se almacenan determinados tipos de archivos en ellas, ASP.NET los trata de manera especial. Carpeta Bin Puede almacenar ensamblados compilados en esta carpeta y el resto del código de cualquier parte de la aplicación Web (como el de las páginas) hará referencia a ella automáticamente. Un ejemplo típico es el código compilado de una clase personalizada. Puede copiar el ensamblado compilado en la carpeta Bin de la aplicación Web y, a continuación, la clase estará disponible para todas las páginas. 143 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Los ensamblados de la carpeta Bin no necesitan registrarse. La presencia de un archivo .dll en la carpeta Bin es suficiente para que ASP.NET lo reconozca. Si cambia el archivo .dll y escribe una nueva versión del mismo en la carpeta Bin, ASP.NET detectará la actualización y utilizará la nueva versión para las nuevas solicitudes de página a partir de ese momento. Seguridad de la carpeta Bin La colocación de los ensamblados compilados en la carpeta Bin pueden comprometer la seguridad. Sin embargo, se deberá tratar el código compilado de la carpeta Bin como cualquier otro código ejecutable. Se debe tener cuidado con el código compilado hasta que se haya probado. Tener en cuenta los siguientes aspectos de seguridad al colocar el código compilado en la carpeta Bin: El ámbito de los ensamblados de la carpeta Bin es la aplicación actual. Por consiguiente, no se pueden tener acceso a recursos ni invocar código que se encuentre fuera de la aplicación Web actual. En tiempo de ejecución, los niveles de acceso de un ensamblado se establecen de acuerdo con el nivel de confianza especificado en el equipo local. Si se está trabajando con un diseñador como Visual Studio, el código de la carpeta Bin se ejecuta en un contexto distinto del contexto en tiempo de ejecución. Carpeta App_Code Si se almacena el código fuente en la carpeta App_Code, se compilará automáticamente en tiempo de ejecución. Al ensamblado resultante puede tener acceso cualquier otro código de la aplicación Web. Por tanto, la carpeta App_Code funciona como la carpeta Bin, salvo que se puede almacenar código fuente en lugar de código compilado. La carpeta App_Code y su estado especial en una aplicación Web ASP.NET permiten crear clases personalizadas y otros archivos que sólo contienen código fuente, y utilizarlos en la aplicación Web sin tener que compilarlos independientemente. Esta carpeta puede contener archivos de código fuente escritos como archivos de clase tradicionales (es decir, archivos con extensión .vb, .cs, etc.). Sin embargo, también puede incluir archivos que no sean explícitamente de un lenguaje de programación específico. Entre los ejemplos cabe destacar los archivos .wsdl (lenguaje de descripción de servicios Web) y los archivos de esquema XML (.xsd). ASP.NET puede compilar estos archivos en ensamblados. La carpeta App_Code puede contener todos los archivos y subcarpetas que se necesiten. Se puede organizar el código fuente de la forma que se crea más conveniente, ASP.NET lo compilará en un solo ensamblado al que podrá tener acceso el código de cualquier parte de la aplicación Web. Nota No se permiten controles de usuario en la carpeta App_Code. Esto afecta tanto a los controles de usuario de un solo archivo como a los controles de usuario que utilizan el modelo de código subyacente. Al colocar un control de usuario en el directorio App_Code, el código del control de usuario se compila fuera de la secuencia requerida y, por tanto, no se permite. Tener en cuenta que no es necesario que los controles de usuario estén en la carpeta App_Code, porque están disponibles para las páginas en cualquier lugar de la aplicación. Deducir el lenguaje de programación de la carpeta App_Code El contenido de la carpeta App_Code no se marca explícitamente como escrito en un lenguaje de programación concreto. ASP.NET deduce el compilador que se debe invocar para la carpeta App_Code basándose en los archivos que contiene. Si la carpeta App_Code contiene archivos .vb, ASP.NET utiliza el compilador de Visual Basic; si contiene archivos .cs, el compilador de C#, etc. Si la carpeta App_Code contiene sólo archivos cuyo lenguaje de programación es ambiguo, como un archivo .wsdl, ASP.NET utilizará el compilador predeterminado para aplicaciones Web, tal como viene configurado en el elemento compilation de la aplicación Web o en el archivo de configuración del equipo. Varios lenguajes de programación en la carpeta App_Code Puesto que el código fuente de la carpeta App_Code se compila en un solo ensamblado, todos los archivos de esta carpeta deben estar escritos en el mismo lenguaje de programación. Por ejemplo, la carpeta App_Code no puede incluir código fuente escrito en Visual Basic y C#. 144 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Sin embargo, es posible configurar la aplicación Web para tratar las subcarpetas de la carpeta App_Code compilables separadas. Cada carpeta puede contener código fuente de un lenguaje de programación diferente. La especifica creando un elemento codeSubDirectories en el elemento compilation del archivo Web.config y agregando la subcarpeta. En el ejemplo siguiente se muestra la configuración de las subcarpetas denominadas VBCode compilar en ensamblados separados: como unidades configuración se una referencia a y CSCode para <compilation debug="false"> <codeSubDirectories> <add directoryName="VBCode" /> <add directoryName="CSCode" /> </codeSubDirectories> </compilation> Las referencias a las subcarpetas VBCode y CSCode no tienen por qué incluir información acerca del lenguaje de programación que contiene la subcarpeta. Como en el caso de la propia carpeta App_Code, ASP.NET deduce el compilador que se va a utilizar basándose en los archivos de la subcarpeta. Seguridad de la carpeta App_Code Los problemas de seguridad relacionados con el código de la carpeta App_Code son básicamente los mismos que los del código de la carpeta Bin (el código se compila en un ensamblado en tiempo de ejecución). Un factor atenuante es que el código de los archivos de la carpeta App_Code se puede leer. Sin embargo, si no se entiende el código, puede seguir comprometiendo la seguridad. Por consiguiente, tratar el código fuente de la carpeta App_Code como si se tratara de código compilado procedente del mismo origen. 37 IMPLEMENTAR EL ESTADO DE SESIÓN, VER EL ESTADO, CONTROLAR EL ESTADO, COOKIES, CACHÉ O ESTADO DE LA APLICACIÓN Información general sobre la administración de estados de ASP.NET Cada vez que la página se envía al servidor, se crea una nueva instancia de la clase de la página Web. En la programación Web tradicional, esto se traduce en que toda la información asociada a la página y sus controles se pierden con cada recorrido de ida y vuelta. Por ejemplo, si un usuario escribe información en un cuadro de texto, dicha información se perderá en el recorrido de ida y vuelta desde el explorador o dispositivo cliente al servidor. Para superar esta limitación inherente de la programación Web tradicional, ASP.NET incluye varias opciones que ayudan a preservar los datos en cada página y en toda la aplicación. Estas características son las siguientes: Estado de vista Estado de control Campos ocultos Cookies Cadenas de consulta Estado de aplicación Estado de sesión Propiedades de perfil Las características de estado de vista, estado de control, campos ocultos, cookies y cadenas de consulta almacenan todas ellas datos en el cliente de formas distintas, mientras que las características de estado de aplicación, estado de sesión y propiedades de perfil almacenan los datos en la memoria del servidor. Cada opción tiene ventajas y desventajas, dependiendo del escenario. Opciones de administración de estado basada en cliente Las siguientes secciones describen opciones para administrar el estado que almacenan la información en la página o en el equipo cliente. En estas opciones, la información no se conserva en el servidor entre acciones de ida y vuelta. 145 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Estado de vista La propiedad ViewState proporciona un objeto de diccionario para conservar valores entre las distintas solicitudes de una misma página. Éste es el método predeterminado que la página utiliza para conservar los valores de las propiedades de la propia página y sus controles entre recorridos de ida y vuelta. Cuando se procesa la página, se calcula el valor de hash del estado actual de la página y de los controles en una cadena y se guarda en la página como campo oculto o varios campos ocultos si el volumen de los datos almacenados en la propiedad ViewState supera el valor especificado en la propiedad MaxPageStateFieldLength. Cuando se devuelve la página al servidor, la página analiza la cadena de estado de vista durante su inicialización y restaura la información de las propiedades en la página. En un estado de vista se puede también almacenar valores. Estado de control En ocasiones es necesario almacenar los datos del estado de control para que un control funcione correctamente. Por ejemplo, si ha escrito un control personalizado con varias fichas que muestran distintos tipos de información, el control debe saber la ficha que se selecciona en los recorridos de ida y vuelta para que funcione tal y como se espera. La propiedad ViewState se puede utilizar para este propósito, pero los desarrolladores pueden desactivar el estado de vista en el nivel de página, interrumpiendo su control eficazmente. Para resolver este problema, el marco de trabajo de la página ASP.NET cuenta con una característica de ASP.NET denominada "estado de control". La propiedad ControlState permite mantener la información de las propiedades que es específica de un control y que no se puede desactivar como ocurre con la propiedad ViewState. Campos ocultos ASP.NET permite almacenar información en un control HiddenField, que se representa como campo oculto estándar HTML. Un campo oculto no se representa visiblemente en el explorador, pero se pueden configurar sus propiedades igual que las de un control estándar. Cuando se envía una página al servidor, el contenido del campo oculto se envía en la colección Form de HTTP junto con los valores de otros controles. Un campo oculto actúa como repositorio de cualquier información específica de página que desee almacenar directamente en la página. Nota sobre la seguridad Es fácil que un usuario malintencionado vea y modifique el contenido de un campo oculto. No almacenar ninguna información que sea confidencial o en la que se base la aplicación para funcionar correctamente en un campo oculto. Un control HiddenField almacena una única variable en su propiedad Value y se debe agregar en la página de forma explícita. Para que los valores de los campos ocultos estén disponibles durante el procesamiento de la página, debe enviarla mediante el método POST de HTTP. Si utiliza campos ocultos y una página se procesa como respuesta a un vínculo o a un comando GET de HTTP, los campos ocultos no estarán disponibles. Cookies Una cookie es una cantidad pequeña de datos que se almacena en un archivo de texto en el sistema de archivos del cliente o que se mantiene en la memoria durante la sesión del explorador cliente. Contiene información específica del sitio que el servidor envía al cliente junto con el resultado de la página. Las cookies pueden ser temporales (con fechas y horas de expiración específicas) o permanentes. Las cookies se pueden utilizar para almacenar información acerca de un cliente, sesión o aplicación específicos. Las cookies se guardan en el dispositivo cliente y, cuando el explorador solicita una página, el cliente envía la información de la cookie junto con la información de la solicitud. El servidor puede leer la cookie y extraer su valor. Uno de los usos típicos es almacenar un símbolo (puede que cifrado) que indica que el usuario ya se ha autenticado en la aplicación. 146 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Nota sobre la seguridad El explorador sólo puede devolver los datos al servidor que creó la cookie. Sin embargo, algunos usuarios malintencionados cuentan con medios para tener acceso a las cookies y leer su contenido. Se recomienda no almacenar información confidencial, como el nombre de usuario o la contraseña, en una cookie. En su lugar, almacene un símbolo (token) en la cookie que identifique al usuario y, a continuación, utilice el símbolo para buscar la información confidencial en el servidor. Cadenas de consulta Una cadena de consulta es información que se anexa al final de la dirección URL de una página. Un ejemplo típico de cadena de consulta podría tener el siguiente aspecto: En la ruta URL indicada, la cadena de consulta empieza por un signo de interrogación (?) e incluye dos pares de atributo-valor; uno de ellos se denomina "category" y el otro, "price". Las cadenas de consulta proporcionan una manera sencilla pero limitada de mantener la información de estado. Por ejemplo, es una manera sencilla de pasar información de una página a otra, por ejemplo, pasar un código de producto de una página a otra donde se procesará. Sin embargo, en algunos exploradores y dispositivos de cliente la longitud de la dirección URL tiene una limitación de 2083 caracteres. Nota sobre la seguridad La información que se pasa en una cadena de consulta puede ser manipulada por un usuario malintencionado. No utilice cadenas de consulta para transmitir información importante o confidencial. Además, un usuario puede marcar la dirección URL o puede enviarla a otros usuarios, pasando esa información con la dirección URL. Para que los valores de las cadenas de consulta estén disponibles durante el procesamiento de la página, debe enviar la página utilizando el método GET de HTTP. Es decir, no puede utilizar las cadenas de consulta si la página se procesa como respuesta a un método POST de HTTP. Opciones de administración de estado basada en servidor ASP.NET proporciona una serie de medios para mantener la información de estado en el servidor, en lugar de conservarla en el cliente. Con la administración de estados basada en servidor, puede reducir la cantidad de información que se envía al cliente para conservar el estado, sin embargo, puede suponer un uso excesivo de los recursos del servidor. En las secciones siguientes se describen tres características de la administración de estados basada en servidor: estado de aplicación, estado de sesión y propiedades de perfiles. Estado de aplicación ASP.NET permite guardar valores utilizando el estado de sesión, que es una instancia de la clase HttpApplicationState, de cada aplicación Web activa. El estado de aplicación es un mecanismo de almacenamiento global al que se puede obtener acceso desde todas las páginas de la aplicación Web. Por tanto, el estado de aplicación resulta útil para almacenar la información que se debe mantener en los recorridos de ida y vuelta del servidor y entre las solicitudes de las páginas. El estado de aplicación se almacena en un diccionario de tipo clave-valor que se crea cada vez que se envía una solicitud a una dirección URL específica. Puede agregar información específica de la aplicación a esta estructura para almacenarla entre las solicitudes de página. Después de agregar la información específica de la aplicación a estado de aplicación, el servidor se encarga de administrarla. Estado de sesión ASP.NET permite guardar valores utilizando el estado de sesión, que es una instancia de la clase HttpSessionState, de cada sesión de una aplicación Web activa. Estado de sesión es similar a estado de aplicación, con la diferencia de que el ámbito es la actual sesión del explorador. Si hay varios usuarios utilizando la aplicación, cada uno de ellos tendrá un estado de sesión distinto. Asimismo, si un usuario sale de la aplicación y vuelve más tarde, el segundo usuario tendrá un estado de sesión distinto al del primero. 147 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 El estado de sesión tiene la estructura de un diccionario de tipo clave-valor para almacenar información específica de cada sesión que se debe conservar en recorridos de ida y vuelta del servidor, así como entre solicitudes de páginas. Puede utilizar el estado de sesión para llevar a cabo las tareas siguientes: Identificar unívocamente las solicitudes del explorador o del dispositivo de cliente y asignarlas a una instancia de sesión individual en el servidor. Almacenar en el servidor datos específicos de la sesión para utilizarlos a través de múltiples solicitudes del explorador o dispositivo dentro de la misma sesión. Producir eventos de administración de sesión adecuados. Adicionalmente, puede escribir código de aplicación para aprovechar estos eventos. Después de agregar la información específica de la aplicación a estado de sesión, el servidor se encarga de administrar dicho objeto. En función de las opciones especificadas, la información de la sesión se puede almacenar en cookies, en un servidor que no forme parte del proceso, o en un equipo que ejecute Microsoft SQL Server. Propiedades de perfiles ASP.NET proporciona una característica denominada "propiedades de perfiles" que permite almacenar datos específicos del usuario. Esta característica es similar al estado de sesión, salvo que los datos del perfil no se pierden cuando expira la sesión de un usuario. La característica propiedades de perfiles utiliza un perfil ASP.NET, que se guarda en un formato persistente y que se asocia con un usuario específico. El perfil ASP.NET permite administrar con facilidad la información sobre el usuario sin que sea necesario crear y mantener una base de datos propia. Además, el perfil hace que la información del usuario esté disponible mediante una API con establecimiento inflexible de tipos a la que puede obtener acceso desde cualquier punto de la aplicación. Puede almacenar objetos de cualquier tipo en el perfil. La característica de perfil de ASP.NET proporciona un sistema de almacenamiento genérico que permite definir y mantener casi cualquier tipo de datos mientras éstos sigan estando disponibles en un modo de seguridad de tipos. Para utilizar las propiedades de perfiles, se debe configurar un proveedor de perfiles. ASP.NET incluye una clase SqlProfileProvider que permite almacenar los datos del perfil en una base de datos SQL, aunque también puede crear una clase propia de proveedor de perfiles que almacene los datos del perfil en un formato personalizado y disponga de un mecanismo de almacenamiento personalizado, como un archivo XML o incluso un servicio Web. Puesto que los datos colocados en las propiedades de perfiles no se almacenan en la memoria de la aplicación, se conservan cuando se reinician Internet Information Services (IIS) y el proceso de trabajo sin pérdida de datos. Además, las propiedades de perfiles se pueden preservar en varios procesos, como en una granja de servidores web o un hospedaje multiproceso en un único equipo. 38 TRATAR EVENTOS Y CONTROLAR EL FLUJO DE PÁGINAS: eventos de página, eventos de control, eventos de aplicación y eventos de sesión, publicaciones en varias páginas; Response.Redirect, Server.Transfer, IsPostBack, configuración de AutoEventWireup Implementar el controlador Generic. MODELO DE EVENTOS DE CONTROL DE SERVIDOR WEB ASP.NET Una característica importante de ASP.NET es que permite programar páginas Web utilizando un modelo basado en eventos similar al de las aplicaciones de cliente. Como ejemplo sencillo, se puede agregar un botón a una página Web ASP.NET y, a continuación, escribir un controlador de eventos para el evento de clic del botón. Aunque esto es habitual en páginas Web que funcionan exclusivamente con un script de cliente (que controla el evento onclick del botón en HTML dinámico), ASP.NET traslada este modelo al procesamiento basado en servidor. Los eventos producidos por los controles de servidor ASP.NET funcionan de manera diferente a los eventos de las páginas HTML tradicionales o de las aplicaciones Web basadas en el cliente. La diferencia se basa principalmente en la separación existente entre el propio evento y el lugar donde se controla el evento. En las aplicaciones basadas en cliente, los eventos se producen y controlan en el cliente. Sin embargo, en las páginas Web ASP.NET, los eventos asociados a los controles de servidor se originan en el cliente (explorador) pero los controla la página ASP.NET en el servidor Web. Para los eventos que se producen en el cliente, el modelo de control de eventos Web ASP.NET necesita que la información del evento se capture en el cliente y que se transmita un mensaje de evento al servidor mediante un envío HTTP. La página debe interpretar el envío para determinar el evento ocurrido y, a continuación, llamar al método apropiado del código del servidor para controlar dicho evento. 148 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 ASP.NET controla la tarea de capturar, transmitir e interpretar el evento. Al crear controladores de eventos en una página Web ASP.NET, no es necesario saber capturar la información del evento y hacer que esté disponible para el código. En cambio, se pueden crear controladores de eventos casi de la misma forma que en un formulario de cliente tradicional. Sin embargo, hay diversos aspectos del control de eventos en las páginas Web ASP.NET que se deben tener en cuenta. Conjunto de eventos para controles de servidor y páginas Debido a que los eventos de controles de servidor ASP.NET requieren un viaje de ida y vuelta al servidor para procesarse, pueden afectar al rendimiento de una página. Por lo tanto, los controles de servidor ofrecen un conjunto limitado de eventos, normalmente sólo de tipo clic. Algunos controles de servidor admiten los eventos de cambio. Por ejemplo, el control CheckBox de servidor Web produce un evento de cambio CheckedChanged cuando el usuario hace clic en el cuadro. Algunos controles de servidor admiten eventos más abstractos. Por ejemplo, el control de servidor Web Calendar provoca un evento SelectionChanged que es una versión más abstracta del evento de clic. Los eventos que tienen lugar con frecuencia (y que pueden provocarse sin que el usuario lo sepa), como onmouseover, no se pueden usar en los controles de servidor. Los controles de servidor ASP.NET siguen pudiendo llamar a los controladores de cliente para esos eventos. Los controles y la propia página también provocan eventos de ciclo de vida en cada paso del procesamiento, como Init, Load y PreRender. Puede aprovecharse de estos eventos de ciclo de vida en la aplicación. Por ejemplo, en el evento Load de una página, puede establecer valores predeterminados para los controles. Argumentos de eventos Los eventos de los controles y de páginas ASP.NET siguen un modelo de .NET Framework estándar para los métodos de controladores de eventos. Todos los eventos pasan dos argumentos: un objeto que representa al objeto que ha provocado el evento, y un objeto evento que contiene la información específica del evento. El segundo argumento suele ser de tipo EventArgs, pero para algunos controles es de un tipo específico de dicho control. Por ejemplo, para un control ImageButton de servidor Web, el segundo argumento es de tipo ImageClickEventArgs, que incluye información sobre las coordenadas donde el usuario ha hecho clic. Nota Los eventos para la página (como Load) pueden aceptar los dos argumentos estándar, pero en estos argumentos no se pasa ningún valor. Eventos Postback y Non-Postback en controles de servidor En los controles de servidor, algunos eventos, generalmente los de clic, hacen que la página se envíe de vuelta inmediatamente al servidor. Los eventos de cambio en los controles de servidor HTML y de servidor Web, como el control TextBox, no ocasionan que se produzca una acción de envío inmediatamente. En su lugar, se generan la próxima vez que tenga lugar una acción de envío. Nota Si el explorador lo admite, los controles de validación pueden comprobar la entrada de datos del usuario mediante scripts de cliente sin realizar un viaje de ida y vuelta al servidor. Una vez enviada de vuelta una página, se generan los eventos de inicialización (Page_Init y Page_Load) de la misma y, a continuación, se procesan los eventos de control. No se debería crear una lógica de aplicación en la que los eventos de cambio se generen en un orden específico a no ser que se conozca con detalle el procesamiento de los eventos de página. Si resulta útil para una aplicación, se puede especificar que los eventos de cambio provoquen el envío de la página. Los controles de servidor Web que admiten un evento de cambio incluyen la propiedad AutoPostBack. Cuando esta propiedad está establecida como true, el evento de cambio del control provoca el envío inmediato de la página, sin esperar a que se produzca un evento de clic. Por ejemplo, de forma predeterminada, el evento CheckedChanged de un control CheckBox no provoca el envío de la página. Sin embargo, si se establece la propiedad AutoPostBack del control en true, en cuanto un usuario active la casilla, la página se envía al servidor para ser procesada. Nota Para que la propiedad AutoPostBack funcione correctamente, el explorador del usuario deberá estar configurado para permitir la ejecución de scripting. Ésta es la configuración predeterminada en la mayoría de casos. Sin embargo, algunos usuarios deshabilitan el scripting por razones de seguridad. 149 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Eventos reenviados Los controles de servidor Web como Repeater, DataList, GridView, FormView y DetailsView pueden contener controles de botón que a su vez generen eventos. Por ejemplo, cada fila de un control GridView puede contener uno o varios botones creados dinámicamente mediante plantillas. En lugar de que cada botón provoque individualmente un evento, los eventos de los controles anidados se reenvían al control del contenedor. El contenedor produce a su vez un evento genérico ItemCommand con parámetros que permite detectar qué control en concreto ha producido el evento original. Respondiendo a este evento único, puede ahorrarse tener que escribir controles de eventos individuales para cada control secundario. El evento ItemCommand incluye los dos argumentos de evento estándar, un objeto que hace referencia al origen del evento y un objeto de evento que contiene información específica del mismo. Nota Los controles GridView, DataList y otros controles de datos admiten eventos adicionales, como EditCommand, DeleteCommand y UpdateCommand, que son casos especiales de eventos reenviados. En el caso de los botones, se puede utilizar la propiedad CommandArgument para pasar una cadena especificada por el usuario al controlador de eventos, con el fin de ayudar a identificar el botón que ha provocado el evento. Por ejemplo, en un control DataList, los botones provocan el evento ItemCommand. Se puede establecer la propiedad CommandArgument de cada botón en un valor distinto (por ejemplo, el valor de un botón puede ser "ShowDetails" y "AddToShoppingCart" el de otro), y más adelante capturar dichos valores en el controlador de eventos. Enlazar eventos a métodos Un evento es un mensaje parecido a "se ha hecho clic en un botón". En una aplicación, se debe traducir el mensaje en una llamada a un método del código. El enlace entre el mensaje del evento y un método específico (es decir, un controlador de evento) se lleva a cabo utilizando un delegado de eventos. En las páginas Web ASP.NET, no es necesario codificar explícitamente delegados si el control se crea mediante declaración (en el marcado) en la página. El enlace de eventos se puede lograr de distintas maneras, dependiendo del evento que se enlace y de qué lenguaje de programación se esté utilizando. Enlazar eventos de control Para controles declarados en la página, se puede enlazar un evento a un método estableciendo un atributo (propiedad) en el marcado del control. El ejemplo de código siguiente muestra cómo enlazar el evento Click de un control ASP.NET Button a un método denominado ButtonClick. <asp:button id="SampleButton" runat="server" text="Submit" onclick="ButtonClick" /> Al compilar la página, ASP.NET busca un método denominado ButtonClick y confirma que éste tiene la firma adecuada (acepta dos argumentos, uno de tipo Object y otro de tipo EventArgs). A continuación, ASP.NET enlaza automáticamente el evento al método. En Visual Basic, también se pueden enlazar los eventos a los métodos utilizando la palabra clave Handles en la declaración del controlador de eventos. Enlazar eventos de página Las páginas ASP.NET provocan eventos de ciclos de vida como Init, Load, PreRender y otros. De manera predeterminada, los eventos de página se pueden enlazar a los métodos utilizando la convención de nomenclatura Page_nombreDeEvento. Por ejemplo, con el fin de crear un controlador para el evento Load de la página, se puede crear un método denominado Page_Load. En tiempo de ejecución, ASP.NET buscará los métodos que se basen en esta convención de nomenclatura y realizará el enlace automáticamente entre el evento y el método. Se puede utilizar la convención Page_nombreDeEvento para cualquier evento expuesto por la clase Page. 150 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Nota Los métodos de control de eventos de página no requieren ningún argumento. Si se prefiere, puede enlazar explícitamente los controladores a los eventos. Una propiedad de página denominada AutoEventWireup controla el enlace automático de los eventos de página en función de la convención de nomenclatura del método. De manera predeterminada, para C#, esta propiedad se establece en true y ASP.NET realiza la búsqueda automática y el enlace descritos anteriormente. También se puede establecer esta propiedad en false agregando el atributo AutoEventWireup=false de la directiva @ Page. A continuación se pueden crear los métodos con cualquier nombre y enlazarlos a los eventos de páginas explícitamente. De forma predeterminada, para Visual Basic, esta propiedad está establecida en false. En Visual Basic, los controladores se enlazan a los eventos mediante la palabra clave Handles. Visual Studio inserta automáticamente esta palabra clave como parte del método que se crea al seleccionar un evento de página en el cuadro desplegable. Una desventaja del atributo AutoEventWireup es que precisa que los controladores de eventos de la página tengan nombres específicos y predecibles. Esto limita su flexibilidad en cuanto al modo de denominar los controladores de eventos. Otra desventaja es el efecto negativo sobre el rendimiento porque ASP.NET busca los métodos en tiempo de ejecución. Para un sitio web con un gran volumen de tráfico, este impacto podría ser significativo. Nota Si incluye enlaces explícitos para los eventos de página, asegurarse de que la propiedad AutoEventWireup esté establecida en false para que no se llame dos veces al método. Enlace explícito para controles dinámicos Si se crea controles declarándolos en el marcado, puede enlazar eventos con métodos mediante un atributo (por ejemplo, onclick) o, en Visual Basic, con la palabra clave Handles. Si los controles se crean dinámicamente (en código), no se puede utilizar ninguno de estos métodos, porque el compilador no tiene una referencia al control en tiempo de compilación. En ese caso, se debe utilizar el enlace de eventos explícito. En Visual Basic, puede utilizar la instrucción AddHandler para enlazar a un método existente un evento creado dinámicamente en un control. En C#, se crea un delegado y se asocia al evento de control. El ejemplo de código siguiente muestra cómo se puede enlazar un método denominado ButtonClick al evento Click de un botón: Button b = new Button; b.Text = "Click"; b.Click += new System.EventHandler(ButtonClick); Placeholder1.Controls.Add(b); Responder a eventos de cliente y de servidor en controles de servidor ASP.NET En este tema se explica cómo trabajar con eventos generados en el código de servidor. Los controles representan los elementos para el explorador y esos elementos también pueden provocar eventos de cliente que se pueden controlar en los scripts de cliente. Mediante el uso de scripts de cliente, se puede agregar la capacidad de control de eventos de mouse y de teclado a los controles de servidor ASP.NET. Eventos de aplicación y de sesión Aparte de los eventos de página y de control, ASP.NET proporciona formas de trabajar con eventos de ciclo de vida que pueden provocarse al iniciarse o detenerse la aplicación, o cuando la sesión de usuario de un individuo determinado se inicia o se detiene, incluido lo siguiente: Los eventos de aplicación se provocan para todas las solicitudes que se hacen a una aplicación. Por ejemplo, el evento BeginRequest del objeto HttpApplication (Application_BeginRequest)) se genera cuando se solicita cualquier página Web ASP.NET o servicio Web XML en una aplicación. Este evento le permite inicializar recursos que se utilizarán para cada solicitud a la aplicación. Un evento correspondiente, el evento EndRequest del objeto HttpApplication (Application_EndRequest), le proporciona la oportunidad de cerrar o eliminar los recursos utilizados por la solicitud. 151 GALA Manual 70-562 TS: Desarrollo de Aplicaciones ASP.Net Utilizando la Plataforma Microsoft .Net 3.5 Los eventos de sesión son similares a los de aplicación (existen los eventos Start y un evento End), pero se producen con cada sesión única dentro de la aplicación. Una sesión comienza cuando un usuario solicita una página por primera vez desde la aplicación y termina cuando la aplicación cierra explícitamente la sesión o cuando la sesión excede el tiempo de espera. Nota El evento Session_End no se provoca en todas las circunstancias. Se pueden crear controladores para estos tipos de eventos en el archivo Global.asax. PagesSection.AutoEventWireup (Propiedad) Obtiene o establece un valor que indica si los eventos para las páginas ASP.NET se conectan automáticamente a las funciones de control de eventos. Valor de propiedad Es true si los eventos para las páginas ASP.NET se conectan automáticamente a las funciones de control de eventos; de lo contrario, es false. El valor predeterminado es true. Cuando AutoEventWireup es true, ASP.NET no exige que los eventos especifiquen los controladores de eventos como Page_Load o Page_Init. Esto significa que, en la página de formulario Web Forms en Visual Basic, no es necesaria la palabra clave Handles en la secuencia de comandos del servidor. De manera predeterminada, cuando la aplicación Web ASP.NET se crea en Visual Studio, el valor del atributo AutoEventWireup de la página .aspx o del control .ascx se establece en false y no se crean controladores de eventos automáticamente. No se establezca AutoEventWireup en true si el rendimiento es una consideración clave. HttpResponse.Redirect (Método) Redirecciona un cliente a una nueva dirección URL y especifica la nueva URL. Parámetros url Ubicación de destino. HttpException La redirección se intenta cuando se han enviado los encabezados HTTP. Llamar a Redirect equivale a llamar a Redirect con el segundo parámetro establecido en true. Redirect llama a End, que inicia una excepción ThreadAbortException al finalizar. Nota: Únicamente en el caso de páginas móviles, si la aplicación se basa en sesiones sin cookies o puede recibir solicitudes de dispositivos móviles que requieren sesiones sin cookies, el uso de una tilde ("~") en una ruta de acceso puede dar lugar a la creación inadvertida de una nueva sesión y a la pérdida potencial de los datos de la sesión. Para establecer una propiedad en un control móvil con una ruta de acceso como "~/ruta de acceso", resuelva la ruta utilizando ResolveUrl "~/ruta de acceso" antes de su asignación a la propiedad. 152