Marcos de Desarrollo Diseño e implementación de aplicaciones Web con .NET Objetivos Conocer la estructura de una aplicación Web ASP.NET Saber escribir código que reaccione a eventos a nivel de aplicación Conocer las opciones de configuración de una aplicación Web Aprender a tratar excepciones en ASP.NET Estructura de directorios de una aplicación Web ASP.NET Directorio Bin Descripción Contiene todos los ensamblados .NET precompilados (normalmente DLLs) que usa la aplicación web ASP.NET (incluido el de la propia aplicación) App_Code Contiene ficheros de código fuente que se compilan dinámicamente. Sólo se usa en Web Site (no en Web Project) App_GlobalResources Archivos de recursos globales, accesibles a cada página en la aplicación Web App_LocalResources Archivos de recursos locales (accesibles desde su página) App_WebRerefences Referencias a servicios web App_Data Reservado para almacenamiento de datos (archivos de BD SQL Server Express y archivos XML) App_Browsers Definiciones de navegadores en XML. Definen las capacidades de renderizado de cada navegador App_Themes Temas usados por la aplicación El archivo de aplicación Global.asax Diseño e implementación de aplicaciones Web con .NET Global.asax Permite escribir manejadores que reaccionan a eventos globales de la aplicación No se puede solicitar el archivo Global.asax directamente. El código se ejecuta automáticamente en respuesta a eventos Los métodos de este archivo tienen nombres predefinidos Sólo puede haber un archivo Global.asax por aplicación (aunque es opcional) y debe residir en el directorio raíz de la aplicación Para añadir: Add > New Item > Global Application Class En una aplicación Web de tipo Web Project, VS creará: Global.asax Global.asax.cs: código Global.asax.cs public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { } protected void Session_Start(object sender, EventArgs e) { } protected void Application_BeginRequest(object sender, EventArgs e) { } Global.asax.cs protected void Application_AuthenticateRequest(object sender, EventArgs e) { } protected void Application_Error(object sender, EventArgs e) { } protected void Session_End(object sender, EventArgs e) { } protected void Application_End(object sender, EventArgs e) { } } Eventos de la aplicación Se puede manejar dos tipos de eventos: Los que ocurren siempre para cada request Los que ocurren sólo bajo ciertas condiciones Eventos de la aplicación por cada request Extraído de (MacDonald, 2010) Eventos de la aplicación por cada request 1. 2. 3. 4. 5. 6. Application_BeginRequest(): se llama al comienzo de cada request Application_AuthenticateRequest(): justo antes de que se realice la autenticación Application_AuthorizeRequest(): después de que el usuario se autentique se determinan sus permisos Application_ResolveRequestCache(): se usa comúnmente en conjunción con caché de salida (output caching). Con caché de salida, el HTML renderizado de un WF se reutiliza, sin ejecutar de nuevo su código. Sin embargo, este manejador de eventos sí se ejecuta En este punto, la request es gestionada por el manejador apropiado. Por ejemplo, para una solicitud de un WF, este es el punto en el que se compila e instancia la página (si es necesario) Application_AcquireRequestState(): se llama justo antes de que se recupere del cliente información específica de la sesión y se use para rellenar la colección Session Eventos de la aplicación por cada request Application_PreRequestHandlerExecute(): se llama antes de que el manejador HTTP apropiado ejecute la request 8. En este punto, el manejador apropiado ejecuta la request. Por ejemplo, si es una solicitud de un WF, se ejecuta el código para gestionar eventos de la página, y la página se renderiza a HTML 9. Application_PostRequestHandlerExecute(): se llama justo después de que la request sea manejada 10. Application_ReleaseRequestState(): se llama cuando la información de la sesión está a punto de ser serializada para que esté disponible para la próxima solicitud 11. Application_UpdateRequestCache(): se llama justo antes de que se añada información a la caché de salida. Por ejemplo, si se ha habilitado la caché de salida para una página, ASP.NET insertará el HTML renderizado para la página en la caché en este punto 12. Application_EndRequest se llama al final de la request, justo antes de que los objetos sean liberados 7. Eventos de la aplicación que no se disparan cada request 1. Application_Start(): se invoca cuando la aplicación arranca por primera vez y se crea el dominio de aplicación 2. Session_Start(): se invoca cada vez que se inicia una nueva sesión 3. 4. Este es un lugar útil para proporcionar código de inicialización para la aplicación Normalmente se utiliza para inicializar información específica del usuario Application_Error(): se invoca si ocurre una excepción no controlada Session_End(): se invoca si termina la sesión del usuario Una sesión finaliza cuando el código la libera explícitamente o cuando expira después de que no se hayan recibido requests en un período de tiempo dado (normalmente 20 minutos) Eventos de la aplicación que no se disparan cada request 5. Application_End(): se llama justo antes de que la aplicación termine 6. El fin de una aplicación puede ocurrir porque: se está reiniciando el IIS o porque la aplicación está transicionando a un nuevo dominio de aplicación (por ejemplo, en respuesta a una actualización de archivos) Application_Disposed(): se invoca un poco después de que la aplicación haya sido apagada. El recolector de basura libera la memoria. ASP.NET: Configuración Diseño e implementación de aplicaciones Web con .NET Configuración ASP.NET La configuración de una aplicación ASP.NET se realiza mediante archivos XML Se pueden modificar en cualquier momento sin reiniciar la aplicación Es fácil acceder a ellos y reemplazarlos (por ejemplo, por ftp) Son fáciles de comprender y editar machine.config y web.config machine.config Se ubica en: c:\Windows\Microsoft.NET\Framework\[Version]\Con fig Define secciones soportadas en ficheros de configuración, configura el proceso de ASP.NET, registra proveedores, etc. En el mismo directorio, se ubica un fichero web.config que contiene configuración adicional Todas las aplicaciones web en la máquina heredan la configuración en estos dos ficheros Algunos de estos aspectos de configuración no aplican cuando se realiza el deploy a un servidor web IIS, que tiene su propio fichero de configuración: ApplicationHost.config web.config Toda aplicación hereda la configuración del archivo machine.config y web.config raíz Adicionalmente se puede aplicar configuración a cada aplicación individual Para esto se puede incluir un archivo web.config en el directorio raíz de la aplicación Adicionalmente, es posible incluir archivos web.config en los subdirectorios Interesante para definir distintas configuraciones de seguridad ASP.NET usa herencia de configuración, de modo que cada subdirectorio adquiere la configuración de su directorio padre Herencia de configuración Extraído de (MacDonald, 2010) web.config Web.config inicial (cuando se crea la aplicación) <?xml version="1.0"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> </configuration> Elementos <location> Es una extensión que permite especificar más de un grupo de opciones de configuración en el mismo fichero de configuración Con el atributo path se especifica el subdirectorio o archivo al que se le aplican las opciones de configuración El siguiente ejemplo crea dos secciones de configuración, uno para el directorio actual y otro que aplica sólo a archivos en el subdirectorio Secure <configuration> <system.web> <!-- la configuracion de ASP.NET va aqui --> </system.web> <location path="/Secure"> <system.web> <!-- las opciones de configuración para el subdirectorio Secure van aquí. --> </system.web> </location> </configuration> Elementos <system.web> Contiene todas las opciones de configuración específicas de ASP.NET. Seguridad, gestión del estado, traceado, etc. El esquema de esta sección es fijo (no se puede cambiar la estructura ni añadir elementos) Elementos: authentication, authorization, compilation, customErrors, membership, pages, profile, roleManager, sessionState, trace Elemento <appSettings> Equivalente al mismo elemento en App.config Define pares clave-valor Permite actualizar configuración sin necesidad de recompilar Útil para rutas de archivos, URL de servicios Web, etc. Ejemplo: <configuration> ... <appSettings> <!–- datos específicos de la aplicación van aquí. <add key="websiteName" value="My New Website"/> <add key="welcomeMessage" value="Welcome to my new Website, friend!"/> </appSettings> ... </configuration> --> Elemento <appSettings> Se puede acceder con: ConfigurationManager.AppSettings["clave"] Ejemplo: Label1.Text = ConfigurationManager.AppSettings["websiteName"] Elemento <connectionStrings> Define cadenas de conexión a base de datos <configuration> <connectionStrings> <add name="MiniBankConnString" connectionString="Data Source=.\SQLExpress;Initial Catalog=minibank;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> ... </system.web> </configuration> Acceso con ConfigurationManager.ConnectionStrings ConfigurationManager.ConnectionStrings["websiteName"].ToString(); Secciones personalizadas Existe la posibilidad de definir secciones personalizadas Se leen con: ConfigurationSettings.GetSection("SECTION_NAME") Ejemplo: UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); Acceso mediante la clase Settings Se guardan en Web.config Adicionalmente, VS crea el archivo Settings.settings, en la carpeta Properties de la aplicación Se crea también un archivo Settings.Designer.cs, que incluye propiedades estáticas, que permiten acceder a las opciones de configuración de forma tipada int count = Settings.Default.MiniBank_defaultCount; Web.config <?xml version="1.0"?> <configuration> <applicationSettings> <Es.Udc.DotNet.MiniPortal.Properties.Settings> <setting name="MiniBank_defaultCount" serializeAs="String"> <value>2</value> </setting> <setting name="MiniBank_applicationURL" serializeAs="String"> <value>http://localhost:8081/MiniBank</value> </setting> <Es.Udc.DotNet.MiniPortal.Properties.Settings> </applicationSettings> <system.web> <trace enabled="true" localOnly="true" pageOutput="true" /> <compilation debug="true" /> <sessionState mode="InProc" cookieless="false" timeout="20" /> <customErrors mode="RemoteOnly" defaultRedirect="/errors/error.html"> <error statusCode="404" redirect="/errors/pagenotfound.html" /> </customErrors> </system.web> </configuration> Páginas de Error Diseño e implementación de aplicaciones Web con .NET Páginas de error La ejecución de una aplicación web puede originar excepciones Controladas: las gestiona el código de usuario (e.g. IncorrectPasswordException, DuplicateInstanceException,...) No controladas Originadas por algún tipo de error interno Acceso a base de datos etc. Encapsuladas como excepciones InternalErrorException Páginas de error Página de error ASP.NET permite definir una página a la que se redirecciona en caso de ocurrir una excepción no controlada La página de error se puede definir en dos niveles: Página: atributo PageError Aplicación: sección customErrors del Web.config Páginas de error Definición a nivel de página Atributo PageError <%@ Page Language="C#" CodeBehind="Register.aspx.cs" Inherits="Es.Udc.DotNet.MiniPortal.Web.Pages.User.Register" PageError="InternalError.aspx" %> Páginas de error Definición a nivel de aplicación Sección customErrors del Web.config <customErrors mode="RemoteOnly" defaultRedirect="InternalError.aspx"> </customErrors> Páginas de error Definición a nivel de aplicación Opciones atributo mode On Off Habilita los errores personalizados (<- suele utilizarse en producción) Si no se especifica el atributo defaultRedirect, los usuarios verán un error genérico Deshabilita los errores personalizados (<- suele utilizarse en desarrollo) Esto permite mostrar los errores detallados estándar RemoteOnly Especifica que los errores personalizados sólo deben mostrarse en los clientes remotos Accediendo desde el servidor (en local) se muestran los errores de ASP.NET Éste es el valor predeterminado Páginas de error Definición a nivel de aplicación Adicionalmente, en la sección customErrors se pueden personalizar las respuestas a códigos de estado HTTP: <customErrors mode="RemoteOnly" defaultRedirect="InternalError.aspx"> <error statusCode="403" redirect="NoAccess.htm" /> <error statusCode="404" redirect="FileNotFound.htm" /> </customErrors> Bibliografía Recomendada: M. MacDonald, A. Freeman, M. Szpuszta. Pro ASP.Net 4 in C# 2010. 4th Ed. Apress. 2010.