Skip to content

8. La aplicación [SimuPaie] – version 4 – ASP.NET / multivista / monopágina


Lecturas recomendadas: referencia [1], Desarrollo WEB con ASP.NET 1.1, apartados:

  • Componentes de servidor y controlador de aplicaciones

  • Ejemplos de aplicaciones MVC con componentes de servidor ASP


Ahora analizamos una version derivada de la aplicación ASP.NET de tres capas estudiada anteriormente, a la que se le añaden nuevas funcionalidades. La arquitectura de nuestra aplicación evoluciona de la siguiente manera:

El procesamiento de una solicitud de un cliente se lleva a cabo siguiendo los siguientes pasos:

  1. el cliente realiza una solicitud a la aplicación.
  2. La aplicación procesa esta solicitud. Para ello, puede necesitar la ayuda de la capa [métier], que a su vez puede necesitar la capa [dao] si es necesario intercambiar datos con la base de datos. La aplicación recibe una respuesta de la capa [métier].
  3. En función de esta, elige (3) la vista (= la respuesta) que se enviará al cliente, proporcionándole (4) la información (el modelo) que necesita.
  4. La respuesta se envía al cliente (5)

Aquí tenemos una arquitectura web denominada MVC (Modelo – Vista – Controlador):

  • [Application] es el controlador. Recibe todas las solicitudes del cliente.
  • [Saisies, Simulation, Simulations, ...] son las vistas. Una vista en .NET es código estándar ASP / HTML que contiene componentes que deben inicializarse. Los valores que hay que proporcionar a estos componentes forman el modelo de la vista.

Aquí vamos a implementar el patrón de diseño MVC de la siguiente manera:

  • las vistas serán componentes [View] dentro de una página única [Default.aspx]
  • el controlador es entonces el código [Default.aspx.cs] de esta página única.

Solo las aplicaciones básicas pueden admitir esta implementación MVC. De hecho, en cada solicitud, se instancian todos los componentes de la página [Default.aspx], es decir, todas las vistas. En el momento de enviar la respuesta, el código de control de la aplicación elige una de ellas simplemente haciendo visible el componente [View] correspondiente y ocultando los demás. Si la aplicación tiene muchas vistas, la página [Default.aspx] tendrá muchos componentes y su coste de instanciación puede llegar a ser prohibitivo. Además, el modo [Design] de la página corre el riesgo de volverse inmanejable por tener demasiadas vistas. Este tipo de arquitectura es adecuada para aplicaciones con pocas vistas y desarrolladas por una sola persona. Cuando se puede adoptar, permite desarrollar una arquitectura MVC de forma muy sencilla. Esto es lo que veremos en esta nueva version.

8.1. Las vistas de la aplicación

Las diferentes vistas que se presentan al usuario serán las siguientes:

  • la vista [VueSaisies], que muestra el formulario de simulación
  • la vista [VueSimulation] utilizada para mostrar el resultado detallado de la simulación:
  • la vista [VueSimulations], que muestra la lista de simulaciones realizadas por el cliente
  • la vista [VueSimulationsVides], que indica que el cliente no tiene simulaciones o ya no las tiene:
  • la vista [VueErreurs], que indica uno o varios errores:

8.2. El proyecto Visual Web Developer de la capa [web]

El proyecto Visual Web Developer de la capa [web] es el siguiente:

  • En [1] encontramos:
  • el archivo de configuración [Web.config] de la aplicación – es idéntico al de la aplicación anterior.
  • el archivo [Global.cs], que gestiona los eventos de la aplicación web, en este caso su inicio, es idéntico al de la aplicación anterior, salvo que también gestiona el inicio de la sesión de usuario.
  • El formulario [Default.aspx] de la aplicación – contiene las diferentes vistas de la aplicación.
  • En [2] se encuentran las referencias del proyecto, que son idénticas a las del anterior version

8.3. El archivo [Global.cs]

El archivo [Global.cs], que gestiona los eventos de la aplicación web, es idéntico al de la aplicación anterior, salvo que además gestiona el inicio de la sesión de usuario:

Global.cs


using System;
using System.Web;
using Pam.Dao.Entites;
using Pam.Metier.Service;
using Spring.Context.Support;
using System.Collections.Generic;
using istia.st.pam.web;

namespace pam_v4
{
    public class Global : HttpApplication
    {

        // --- datos estáticos de la aplicación ---
        public static Employe[] Employes;
        public static string Msg = string.Empty;
        public static bool Erreur = false;
        public static IPamMetier PamMetier = null;

        // inicio de la aplicación
        public void Application_Start(object sender, EventArgs e)
        {
...
        }

        // inicio de la sesión de un usuario 
        public void Session_Start(object sender, EventArgs e)
        {
            // se inserta una lista de simulaciones vacía en la sesión 
            Session["simulations"] = new List<Simulation>();
        } 

    }
}
  • líneas 27-34: se gestiona el inicio de la sesión. En ella incluiremos la lista de simulaciones realizadas por el usuario.
  • línea 30: se crea una lista de simulaciones vacía. Una simulación es un objeto de tipo [Simulation] que detallaremos más adelante.
  • línea 31: la lista de simulaciones se coloca en la sesión asociada a la clave «simulaciones»

8.4. La clase [Simulation]

Un objeto de tipo [Simulation] sirve para encapsular una línea de la tabla de simulaciones:

Su código es el siguiente:


namespace Pam.Web
{

    public class Simulation
    {
        // datos de una simulación 
        public string Nom { get; set; }
        public string Prenom { get; set; }
        public double HeuresTravaillees { get; set; }
        public int JoursTravailles { get; set; }
        public double SalaireBase { get; set; }
        public double Indemnites { get; set; }
        public double CotisationsSociales { get; set; }
        public double SalaireNet { get; set; }

        // constructores 
        public Simulation()
        {

        }

        public Simulation(string nom, string prenom, double heuresTravailllees, int joursTravailles, double salaireBase, double indemnites, double cotisationsSociales, double salaireNet)
        {
            {
                this.Nom = nom;
                this.Prenom = prenom;
                this.HeuresTravaillees = heuresTravailllees;
                this.JoursTravailles = joursTravailles;
                this.SalaireBase = salaireBase;
                this.Indemnites = indemnites;
                this.CotisationsSociales = cotisationsSociales;
                this.SalaireNet = salaireNet;
            }
        }
    }
}

Los campos de la clase corresponden a las columnas de la tabla de simulaciones.

8.5. La página [Default.aspx]

8.5.1. Visión general

La página [Default.aspx] contiene varios componentes [View], uno por cada vista. Su estructura es la siguiente:


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="pam_v4.PagePam" %>

<!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>Simulateur de paie</title>
</head>
<body background="ressources/standard.jpg">
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
    <asp:UpdatePanel runat="server" ID="UpdatePanelPam" UpdateMode="Conditional">
        <ContentTemplate>
            <table>
                <tr>
                    <td>
                        <h2>
                            Simulateur de calcul de paie</h2>
                    </td>
                    <td>
                        <label>
                            &nbsp;&nbsp;&nbsp</label>
                        <asp:UpdateProgress ID="UpdateProgress1" runat="server">
                            <ProgressTemplate>
                                <img src="images/indicator.gif" />
                                <asp:Label ID="Label5" runat="server" BackColor="#FF8000"
                                         EnableViewState="False" Text="Calcul en cours. Patientez ....">
                                        </asp:Label>
                            </ProgressTemplate>
                        </asp:UpdateProgress>
                    </td>
                    <td>
                       <asp:LinkButton ID="LinkButtonFaireSimulation" runat="server" 
                                CausesValidation="False" OnClick="LinkButtonFaireSimulation_Click">
                                    | Faire la simulation<br /></asp:LinkButton>
                       <asp:LinkButton ID="LinkButtonEffacerSimulation" runat="server"
                                     CausesValidation="False" OnClick="LinkButtonEffacerSimulation_Click">
                                    | Effacer la simulation<br /></asp:LinkButton>
                       <asp:LinkButton ID="LinkButtonVoirSimulations" runat="server" 
                                CausesValidation="False" OnClick="LinkButtonVoirSimulations_Click">
                                    | Voir les simulations<br /></asp:LinkButton>
                        <asp:LinkButton ID="LinkButtonFormulaireSimulation" runat="server"
                                CausesValidation="False" OnClick="LinkButtonFormulaireSimulation_Click">
                                | Retour au formulaire de simulation<br /></asp:LinkButton>
                        <asp:LinkButton ID="LinkButtonEnregistrerSimulation" runat="server"
                                CausesValidation="False" OnClick="LinkButtonEnregistrerSimulation_Click">
                                    | Enregistrer la simulation<br /></asp:LinkButton>
                        <asp:LinkButton ID="LinkButtonTerminerSession" runat="server"
                                CausesValidation="False" OnClick="LinkButtonTerminerSession_Click">
                                    | Terminer la session<br /></asp:LinkButton>
                    </td>
            </table>
            <hr />
            <asp:MultiView ID="Vues1" ActiveViewIndex="0" runat="server">
                <asp:View ID="VueSaisies" runat="server">
...
                </asp:View>
            </asp:MultiView>
            <asp:MultiView ID="Vues2" runat="server">
                <asp:View ID="VueSimulation" runat="server">
...
                </asp:View>
                <asp:View ID="VueSimulations" runat="server">
...
                </asp:View>
                <asp:View ID="VueSimulationsVides" runat="server">
...
                </asp:View>
                <asp:View ID="VueErreurs" runat="server">
...
                </asp:View>
            </asp:MultiView>
        </ContentTemplate>
    </asp:UpdatePanel>
    </form>
</body>
</html>
  • línea 10: la etiqueta para disponer de las extensiones Ajax
  • líneas 11-73: el contenedor UpdatePanel actualizado mediante llamadas Ajax
  • líneas 12-72: el contenido del contenedor UpdatePanel
  • líneas 13-52: el encabezado que aparecerá en cada vista. Presenta al usuario la lista de acciones posibles en forma de lista de enlaces.
  • línea 33: cabe destacar el atributo CausesValidation="False", que hace que los validadores de la página no se ejecuten implícitamente al hacer clic en el enlace. Cuando este atributo no está presente, su valor por defecto es True. La validación de la página se podrá realizar explícitamente en el código ejecutado en el lado del servidor mediante la operación Page.Validate.
  • líneas 53-57: un componente [MultiView] con una única vista [VueSaisies]. Por este motivo, se ha fijado en la línea 53 el número de la vista que se va a mostrar: ActiveViewIndex="0"
  • líneas 53-67: un componente [MultiView] con cuatro vistas: la vista [VueSimulation] en las líneas 59-61, la vista [VueSimulations], líneas 62-64, la vista [VueSimulationsVides], líneas 65-67, la vista [VueErreurs], líneas 68-70. Un componente [MultiView] solo muestra una vista a la vez. Para mostrar la vista n.º i del componente Vues2, se escribirá el código:
Vues2.ActiveViewIndex=i

8.5.2. El en cabezal

El encabezado está formado por los siguientes componentes:

N.º
Tipo
Nombre
Función
1
LinkButton
LinkButtonFaireSimulation
solicita el cálculo de la simulación
2
LinkButton
LinkButtonEffacerSimulation
borra el formulario de entrada
3
LinkButton
LinkButtonVoirSimulations
muestra la lista de simulaciones ya realizadas
4
LinkButton
LinkButtonFormulaireSimulation
vuelve al formulario de introducción de datos
5
LinkButton
LinkButtonEnregistrerSimulation
guarda la simulación actual en la lista de simulaciones
6
LinkButton
LinkButtonTerminerSession
cierra la sesión actual

8.5.3. La vista [Saisies]

El componente [View] denominado [VueSaisies] es el siguiente:

N.º
Tipo
Nombre
Función
1
DropDownList
ComboBoxEmployes
Contiene la lista de nombres de los empleados
2
TextBox
TextBoxHeures
Número de horas trabajadas – número real
3
TextBox
TextBoxJours
Número de días trabajados – número entero
4
RequiredFieldValidator
RequiredFieldValidatorHeures
comprueba que el campo [2] [TextBoxHeures] no esté vacío
5
RegularExpressionValidator
RegularExpressionValidatorHeures
comprueba que el campo [2] [TextBoxHeures] es un número real >=0
6
RequiredFieldValidator
RequiredFieldValidatorJours
comprueba que el campo [3] [TextBoxJours] no está vacío
7
RegularExpressionValidator
RegularExpressionValidatorJours
comprueba que el campo [3] [TextBoxJours] sea un número entero >=0

8.5.4. La vista [Simulation]

El componente [View] denominado [VueSimulation] es el siguiente:

Image

Se compone únicamente de componentes [Label], cuyos ID se indican más arriba.

8.5.5. La vista [Simulations]

El componente [View] denominado [VueSimulations] es el siguiente:

N.º
Tipo
Nombre
Función
1
GridView
GridViewSimulations
Contiene la lista de simulaciones

Las propiedades del componente [GridViewSimulations] se han definido de la siguiente manera:

  • en [1]: clic con el botón derecho del ratón sobre [GridView] / option [Mise en forme automatique]
  • en [2]: seleccione un tipo de visualización para el [GridView]
  • en [3]: seleccionar las propiedades del [GridView]
  • en [4]: editar las columnas del [GridView]
  • en [5]: añadir una columna de tipo [BoundField] que se vinculará (bound) a una de las propiedades públicas del objeto que se va a mostrar en la línea de [GridView]. El objeto que se muestra aquí será un objeto de tipo [Simulation].
  • en [6]: indique el título de la columna
  • en [7]: indique el nombre de la propiedad de la clase [Simulation] que se asociará a esta columna.
  • [DataFormatString] indica cómo deben formatearse los valores mostrados en la columna.

Las columnas del componente [GridViewSimulations] tienen las siguientes propiedades:

N.º
Propiedades
2
Tipo: BoundField, HeaderText: Nombre, DataField: Nombre
3
Tipo: BoundField, HeaderText: Apellido, DataField: Nombre
4
Tipo: BoundField, HeaderText: Horas trabajadas, DataField: HeuresTravaillees
5
Tipo: BoundField, HeaderText: Días trabajados, DataField: JoursTravailles
6
Tipo: BoundField, HeaderText: Salario base, DataField: SalaireBase, DataFormatString: {0:C} (formato monetario, C = moneda): mostrará el símbolo del euro.
7
Tipo: BoundField, HeaderText: Indemnizaciones, Data Campo: Indemnites, DataFormatString: {0:C}
8
Tipo: BoundField, HeaderText: Cotizaciones sociales, DataField: CotisationsSociales, DataFormatString: {0:C}
9
Tipo: BoundField, HeaderText: Salario net, DataField: SalaireNet, DataFormatString: {0:C}

Se prestará atención al hecho de que el campo [DataField] debe corresponder a una propiedad existente de la clase [Simulation]. Al final de esta fase, se han creado todas las columnas de tipo [BoundField]:

  • en [1]: las columnas creadas para [GridView]
  • en [2]: la generación automática de columnas debe desactivarse cuando es el desarrollador quien las define por sí mismo, tal y como acabamos de hacer.

Nos queda por crear la columna de enlaces [Retirer]:

  • en [1]: añadir una columna de tipo [CommandField / Supprimer]
  • en [2]: ButtonType=Link para tener un enlace en la columna en lugar de un botón
  • en [3]: CausesValidation=False, al hacer clic en el enlace no se ejecutarán los controles de validación que puedan encontrarse en la página. De hecho, la eliminación de una simulación no requiere ninguna verificación de datos.
  • en [4]: solo será visible el enlace de eliminación.
  • en [5]: el texto de este enlace

8.5.6. La vista [SimulationsVides]

El componente [View] denominado [VueSimulationsVides] contiene simplemente texto:

 

8.5.7. La vista [Erreurs]

El componente [View] denominado [VueErreurs] es el siguiente:

N.º
Tipo
Nombre
Función
1
Repetidor
RptErreurs
muestra una lista de mensajes de error

El componente [Repeater] permite repetir un código ASP.NET / HTML para cada objeto de una fuente de datos, generalmente una colección. Este código se define directamente en el código fuente ASP.NET de la página:


                <asp:Repeater ID="RptErreurs" runat="server">
                    <ItemTemplate>
                        <li>
                            <%# Container.DataItem %>
                        </li>
                    </ItemTemplate>
</asp:Repeater>
  • línea 2: <ItemTemplate> define el código que se repetirá para cada elemento de la fuente de datos.
  • línea 4: muestra el valor de la expresión Container.DataItem que designa el elemento actual de la fuente de datos. Dado que este elemento es un objeto, se utiliza el método ToString de dicho objeto para incluirlo en el flujo HTML de la página. Nuestra colección de objetos será una colección List(Of String) que contiene mensajes de error. Las líneas 3-5 incluirán secuencias <li>Message</li> en el flujo HTML de la página.

8.6. El controlador [Default.aspx.cs]

8.6.1. Descripción general

Volvamos a la arquitectura MVC de la aplicación:

  • [Default.aspx.cs], que es el código de control de la página única [Default.aspx], es el controlador de la aplicación.
  • [Global] es el objeto de tipo [HttpApplication] que inicializa la aplicación y que tiene una referencia a la capa [métier].

El esqueleto del código del controlador [Default.aspx.cs] es el siguiente:


using System.Collections.Generic;
...

public partial class PagePam : Page
{

    private void setVues(bool boolVues1, bool boolVues2, int index)
    {
        // se muestran las vistas solicitadas 
        // boolVues1: true si la vista múltiple Vistas1 debe estar visible 
        // boolVues1: true si la vista múltiple Vistas2 debe estar visible 
        // índice: índice de la vista de Vues2 que se va a mostrar 
...
    }

    private void setMenu(bool boolFaireSimulation, bool boolEnregistrerSimulation, bool boolEffacerSimulation, bool boolFormulaireSimulation, bool boolVoirSimulations, bool boolTerminerSession)
    {
        // se establecen las opciones del menú 
        // cada valor booleano se asigna a la propiedad Visible del enlace correspondiente 
...
    }

    // carga de la página 
    protected void Page_Load(object sender, System.EventArgs e)
    {
        // procesamiento de la solicitud inicial 
        if (!IsPostBack)
        {
...
        }
    }

    protected void LinkButtonFaireSimulation_Click(object sender, System.EventArgs e)
    {
...
    }

    protected void LinkButtonEffacerSimulation_Click(object sender, System.EventArgs e)
    {
....
    }

    protected void LinkButtonVoirSimulations_Click(object sender, System.EventArgs e)
    {
...
    }

    protected void LinkButtonEnregistrerSimulation_Click(object sender, System.EventArgs e)
    {
...
    }

    protected void LinkButtonTerminerSession_Click(object sender, System.EventArgs e)
    {
...
    }

    protected void LinkButtonFormulaireSimulation_Click(object sender, System.EventArgs e)
    {
...
    }


    protected void GridViewSimulations_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {
...
    }
}

En la solicitud inicial (GET) del usuario, solo se procesa el evento Load de las líneas 24-31. En las solicitudes siguientes (POST) realizadas a través de los enlaces del menú, se procesan dos eventos:

  1. el evento Load (24-31), pero la comprobación del booleano Page.IsPostback (línea 27) hace que no se realice ninguna acción.
  2. el evento vinculado al enlace en el que se ha hecho clic:
  • líneas 33-36: gestionan el clic en el enlace [1]
  • líneas 38-41: procesan el clic en el enlace [2]
  • líneas 43-46: gestionan el clic en el enlace [3]
  • líneas 58-61: gestionan el clic en el enlace [4]
  • líneas 48-51: gestionan el clic en el enlace [5]
  • líneas 53-56: gestionan el clic en el enlace [6]

Para factorizar secuencias de código que se repiten con frecuencia, se han creado dos métodos internos:

  • setVues, líneas 7-14: establece la vista o vistas que se mostrarán
  • setMenu, líneas 16-21: establece las opciones de menú que se mostrarán

8.6.2. El evento Load


Lecturas recomendadas: referencia [1], Desarrollo WEB con ASP.NET 1.1:

  • apartado Componente [Repeater] y enlace de datos.

La primera vista que se muestra al usuario es la del formulario vacío:

La inicialización de la aplicación requiere el acceso a una fuente de datos que puede fallar. En ese caso, la primera página es una página de errores:

El evento [Load] se procesa de forma análoga a la de las versiones anteriores ASP.NET:


    // carga de la página 
    protected void Page_Load(object sender, System.EventArgs e)
    {
        // procesamiento de la solicitud inicial 
        if (!IsPostBack)
        {
            // ¿Errores de inicialización? 
            if (Global.Erreur)
            {
                // Visualización de la vista [erreurs] 
...
                // posicionamiento del menú 
                ...
                return;
            }
            // carga de los nombres de los empleados en el combo 
...
            // posicionamiento del menú 
...
            // visualización de la vista [saisie] 
 ...
        }
}

Pregunta: complete el código anterior


8.6.3. Acción: Realizar la simulación

A continuación, la pantalla marcada con (1) es la de la solicitud del usuario, y la marcada con (2), la respuesta que le envía la aplicación web. Desde la pantalla de inicio, el usuario puede iniciar una simulación:

- (1): el usuario solicita una simulación
- (2): resultado de la simulación

El procedimiento que gestiona esta acción podría ser similar al siguiente:


    protected void LinkButtonFaireSimulation_Click(object sender, System.EventArgs e)
    {
        // cálculo del salario 
        // ¿página válida? 
        Page.Validate();
        if (!Page.IsValid)
        {
            // visualización de vista [saisie] 
            ...
            return;
        }
        // la página es válida: se recuperan los datos introducidos 
        double HeuresTravaillées = ...;
        int JoursTravaillés = ...;
        // se calcula el salario del empleado 
        FeuilleSalaire feuillesalaire;
        try
        {
            feuillesalaire = ...
        }
        catch (PamException ex)
        {
            // visualización de la vista [erreurs] 
...
            return;
        }
        // se guarda el resultado en la sesión 
        Session["simulation"] = ...
        // visualización de resultados 
...
        // visualización de vistas [saisie, employe, salaire] 
        ...
        // visualización del menú 
        ...
}

Pregunta: completar el código anterior


8.6.4. Acción: Guardar la simulación

Una vez realizada la simulación, el usuario puede solicitar su grabación:

- (1): solicitud de guardado de la simulación actual
- (2): la simulación se guarda y se muestra la lista de simulaciones realizadas

El procedimiento que gestiona esta acción podría ser similar al siguiente:


    protected void LinkButtonEnregistrerSimulation_Click(object sender, System.EventArgs e)
    {
        // se guarda la simulación actual en la lista de simulaciones de la sesión 
        ...
        // se muestra la vista [simulations] 
        ...
}

Pregunta: complete el código anterior


8.6.5. Acción: Volver al formulario de simulación


Lecturas recomendadas: referencia [1], [Développement WEB avec ASP.NET 1.1 ]: la función del campo oculto _VIEWSTATE


Una vez mostrada la lista de simulaciones, el usuario puede solicitar volver al formulario de simulación:

Cabe señalar que la pantalla (2) muestra el formulario tal y como se ha introducido. Hay que recordar aquí que estas diferentes vistas pertenecen a una misma página. Entre las diferentes consultas, los valores de los componentes se mantienen mediante el mecanismo de ViewState si dichos componentes tienen su propiedad EnableViewState establecida en true.

El procedimiento que gestiona esta acción podría ser similar al siguiente:


    protected void LinkButtonFormulaireSimulation_Click(object sender, System.EventArgs e)
    {
        // visualización de la vista [saisie] 
        ...
        // posicionamiento del menú 
        ...
}

Pregunta: complete el código anterior


8.6.6. Acción: Borrar la simulación

Una vez de vuelta en el formulario de simulación, el usuario puede solicitar que se borren las entradas actuales:

El procedimiento que gestiona esta acción podría ser similar al siguiente:


    protected void LinkButtonEffacerSimulation_Click(object sender, System.EventArgs e)
    {
        // RAZ del formulario 
        ...
}

Pregunta: completar el código anterior


8.6.7. Acción: Ver las simulaciones

El usuario puede solicitar ver las simulaciones que ya ha realizado:

El procedimiento que gestiona esta acción podría ser similar al siguiente:


protected void LinkButtonVoirSimulations_Click(object sender, System.EventArgs e)
    {
        // se recuperan las simulaciones en la sesión
        ...
        // ¿hay simulaciones? 
        if (...)
        {
            // vista [simulations] visible 
...
        }
        else
        {
            // vista [SimulationsVides] 
            ...
        }
        // se fija el menú 
        ...
    }

Pregunta: completa el código anterior


8.6.8. Acción: Eliminar una simulación

El usuario puede solicitar la eliminación de una simulación:

El procedimiento [GridViewSimulations_RowDeleting ] que gestiona esta acción podría tener el siguiente aspecto:


    protected void GridViewSimulations_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {
        // se recuperan las simulaciones de la sesión
        ...
        // se elimina la simulación indicada (e.RowIndex es el n.º de la línea eliminada)
        ...
        // ¿quedan simulaciones? 
        if (...)
        {
            // se rellena el GridView 
 ...
        }
        else
        {
            // vista [SimulationsVides] 
            ...
        }
}

Pregunta: complete el código anterior


8.6.9. Acción: Finalizar la sesión

El usuario puede solicitar finalizar su sesión de simulaciones. Esto descarta el contenido de su sesión y muestra un formulario en blanco:

El procedimiento que gestiona esta acción podría ser similar al siguiente:


    protected void LinkButtonTerminerSession_Click(object sender, System.EventArgs e)
    {
        // se abandona la sesión 
        ...
        // mostrar la vista [saisies] 
        ...
        // posicionamiento del menú 
        ...
}

Pregunta: complete el código anterior


Ejercicio práctico: implementa en el servidor la aplicación web anterior. Añádele funcionalidad Ajax.