8. L'applicazione [SimuPaie] – versione 4 – ASP.NET / multi-vista / pagina singola
Letture consigliate: riferimento [1], Sviluppo WEB con ASP.NET 1.1, paragrafi:
-
Componenti server e controller dell’applicazione
-
Esempi di applicazioni MVC con componenti server ASP
Esaminiamo ora una versione derivata dell'applicazione a tre livelli ASP.NET analizzata in precedenza, alla quale sono state aggiunte nuove funzionalità. L'architettura della nostra applicazione si evolve come segue:
![]() |
L'elaborazione di una richiesta da parte di un cliente si svolge secondo le seguenti fasi:
- il cliente invia una richiesta all'applicazione.
- l'applicazione elabora tale richiesta. A tal fine, potrebbe aver bisogno dell’aiuto del livello [métier], che a sua volta potrebbe aver bisogno del livello [dao] se è necessario scambiare dati con il database. L’applicazione riceve una risposta dal livello [métier].
- In base a tale risposta, sceglie (3) la vista (= la risposta) da inviare al cliente, fornendogli (4) le informazioni (il modello) di cui ha bisogno.
- La risposta viene inviata al cliente (5)
Qui abbiamo un'architettura web denominata MVC (Modello – Vista – Controller):
- [Application] è il controller. Esso riceve tutte le richieste provenienti dal client.
- [Saisies, Simulation, Simulations, ...] sono le viste. Una vista in .NET è costituita da codice standard ASP / HTML che contiene componenti che devono essere inizializzati. I valori da fornire a questi componenti costituiscono il modello della vista.
Qui implementeremo il modello (design pattern) MVC nel modo seguente:
- le viste saranno componenti [View] all’interno di una pagina singola [Default.aspx]
- il controller è quindi il codice [Default.aspx.cs] di questa pagina singola.
Solo le applicazioni di base possono supportare questa implementazione MVC. Infatti, ad ogni richiesta, vengono istanziati tutti i componenti della pagina [Default.aspx], quindi tutte le viste. Al momento di inviare la risposta, una di esse viene scelta dal codice di controllo dell’applicazione semplicemente rendendo visibile il componente [View] corrispondente e nascondendo gli altri. Se l’applicazione presenta numerose viste, la pagina [Default.aspx] avrà molti componenti e il suo costo di istanziazione potrebbe diventare proibitivo. Inoltre, la struttura della pagina [Design] rischia di diventare ingestibile a causa dell’eccessivo numero di viste. Questo tipo di architettura è adatto ad applicazioni con poche viste e sviluppate da una sola persona. Quando è possibile adottarla, consente di sviluppare un’architettura MVC in modo molto semplice. È proprio ciò che vedremo in questa nuova versione.
8.1. Le viste dell’applicazione
Le diverse viste presentate all’utente saranno le seguenti:
- la vista [VueSaisies] che presenta il modulo di simulazione

- la vista [VueSimulation] utilizzata per visualizzare il risultato dettagliato della simulazione:

- la vista [VueSimulations] che fornisce l’elenco delle simulazioni effettuate dal cliente

- la vista [VueSimulationsVides] che indica che il cliente non ha o non ha più simulazioni:

- la vista [VueErreurs] che segnala uno o più errori:

8.2. Il progetto Visual Web Developer del livello [web]
Il progetto Visual Web Developer del livello [web] è il seguente:
![]() |
- in [1] si trova:
- il file di configurazione [Web.config] dell'applicazione – è identico a quello dell'applicazione precedente.
- il file [Global.cs] che gestisce gli eventi dell’applicazione web, in questo caso il suo avvio, è identico a quello dell’applicazione precedente, tranne per il fatto che gestisce anche l’avvio della sessione utente.
- il modulo [Default.aspx] dell'applicazione – contiene le diverse viste dell'applicazione.
- In [2] si trovano i riferimenti del progetto – sono identici a quelli della versione precedente
8.3. Il file [Global.cs]
Il file [Global.cs], che gestisce gli eventi dell’applicazione web, è identico a quello dell’applicazione precedente, tranne per il fatto che gestisce anche l’avvio della sessione utente:
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
{
// --- dati statici dell'applicazione ---
public static Employe[] Employes;
public static string Msg = string.Empty;
public static bool Erreur = false;
public static IPamMetier PamMetier = null;
// avvio dell'applicazione
public void Application_Start(object sender, EventArgs e)
{
...
}
// avvio della sessione di un utente
public void Session_Start(object sender, EventArgs e)
{
// si inserisce un elenco di simulazioni vuoto nella sessione
Session["simulations"] = new List<Simulation>();
}
}
}
- righe 27-34: si gestisce l'avvio della sessione. In essa inseriremo l'elenco delle simulazioni effettuate dall'utente.
- riga 30: viene creato un elenco di simulazioni vuoto. Una simulazione è un oggetto di tipo [Simulation] che approfondiremo tra poco.
- riga 31: l'elenco delle simulazioni viene inserito nella sessione associata alla chiave "simulazioni"
8.4. La classe [Simulation]
Un oggetto di tipo [Simulation] serve a incapsulare una riga della tabella delle simulazioni:

Il suo codice è il seguente:
namespace Pam.Web
{
public class Simulation
{
// dati di una simulazione
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; }
// costruttori
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;
}
}
}
}
I campi della classe corrispondono alle colonne della tabella delle simulazioni.
8.5. La pagina [Default.aspx]
8.5.1. Panoramica
La pagina [Default.aspx] contiene diversi componenti [View], uno per ogni vista. La sua struttura è la seguente:
<%@ 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>
 </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>
- riga 10: il tag per gestire le estensioni Ajax
- righe 11-73: il contenitore UpdatePanel aggiornato tramite chiamate Ajax
- righe 12-72: il contenuto del contenitore UpdatePanel
- righe 13-52: l'intestazione che sarà presente in ogni vista. Presenta all'utente l'elenco delle azioni possibili sotto forma di un elenco di link.
- riga 33: si noti l'attributo CausesValidation="False", che fa sì che i validatori della pagina non vengano eseguiti implicitamente quando si clicca sul link. Quando questo attributo è assente, il suo valore predefinito è True. La convalida della pagina potrà essere effettuata esplicitamente nel codice eseguito lato server tramite l’operazione Page.Validate.
- righe 53-57: un componente [MultiView] con un'unica vista [VueSaisies]. Per questo motivo, alla riga 53 è stato specificato in modo fisso il numero della vista da visualizzare: ActiveViewIndex="0"
- righe 53-67: un componente [MultiView] con quattro viste: la vista [VueSimulation] alle righe 59-61, la vista [VueSimulations] alle righe 62-64, la vista [VueSimulationsVides] alle righe 65-67, la vista [VueErreurs] alle righe 68-70. Un componente [MultiView] visualizza solo una vista alla volta. Per visualizzare la vista n. i del componente Vues2, si scriverà il codice:
8.5.2. L' 'intestazione
L'intestazione è costituita dai seguenti componenti:
![]() |
N. | Tipo | Nome | Ruolo |
LinkButton | LinkButtonFaireSimulation | richiede il calcolo della simulazione | |
LinkButton | LinkButtonEffacerSimulation | cancella il modulo di inserimento dati | |
LinkButton | LinkButtonVoirSimulations | visualizza l'elenco delle simulazioni già effettuate | |
LinkButton | LinkButtonFormulaireSimulation | torna al modulo di inserimento dati | |
LinkButton | LinkButtonEnregistrerSimulation | salva la simulazione corrente nell'elenco delle simulazioni | |
LinkButton | LinkButtonTerminerSession | termina la sessione corrente |
8.5.3. La vista [Saisies]
Il componente [View] denominato [VueSaisies] è il seguente:
![]() |
N. | Tipo | Nome | Ruolo |
DropDownList | ComboBoxEmployes | Contiene l'elenco dei nomi dei dipendenti | |
TextBox | TextBoxHeures | Numero di ore lavorate – numero effettivo | |
TextBox | TextBoxJours | Numero di giorni lavorati – numero intero | |
RequiredFieldValidator | RequiredFieldValidatorHeures | verifica che il campo [2] [TextBoxHeures] non sia vuoto | |
RegularExpressionValidator | RegularExpressionValidatorHeures | verifica che il campo [2] [TextBoxHeures] sia un numero reale >=0 | |
RequiredFieldValidator | RequiredFieldValidatorJours | verifica che il campo [3] [TextBoxJours] non sia vuoto | |
RegularExpressionValidator | RegularExpressionValidatorJours | verifica che il campo [3] [TextBoxJours] sia un numero intero >=0 |
8.5.4. La vista [Simulation]
Il componente [View] denominato [VueSimulation] è il seguente:

È composto esclusivamente da componenti [Label], di cui i ID sono indicati sopra.
8.5.5. La vista [Simulations]
Il componente [View] denominato [VueSimulations] è il seguente:
![]() |
N. | Tipo | Nome | Ruolo |
GridView | GridViewSimulations | Contiene l'elenco delle simulazioni |
Le proprietà del componente [GridViewSimulations] sono state definite come segue:
![]() |
- in [1]: clic destro su [GridView] / opzione [Mise en forme automatique]
- in [2]: selezionare un tipo di visualizzazione per il [GridView]
![]() |
- in [3]: selezionare le proprietà di [GridView]
- in [4]: modificare le colonne del [GridView]
- in [5]: aggiungere una colonna di tipo [BoundField] che sarà collegata (bound) a una delle proprietà pubbliche dell'oggetto da visualizzare nella riga di [GridView]. L'oggetto visualizzato qui sarà un oggetto di tipo [Simulation].
![]() |
- in [6]: specificare il titolo della colonna
- in [7]: specificare il nome della proprietà della classe [Simulation] che sarà associata a questa colonna.
- [DataFormatString] indica come devono essere formattati i valori visualizzati nella colonna.
Le colonne del componente [GridViewSimulations] presentano le seguenti proprietà:
N. | Proprietà |
Tipo: BoundField, HeaderText: Nome, DataField: Nome | |
Tipo: BoundField, HeaderText: Cognome, DataField: Nome | |
Tipo: BoundField, HeaderText: Ore lavorate, DataField: HeuresTravaillees | |
Tipo: BoundField, HeaderText: Giorni lavorati, DataField: JoursTravailles | |
Tipo: BoundField, HeaderText: Stipendio base, DataField: SalaireBase, DataFormatString: {0:C} (formato monetario, C=Valuta) – visualizzerà il simbolo dell’euro. | |
Tipo: BoundField, HeaderText: Indennità, Campo dati: Indennità, DataFormatString: {0:C} | |
Tipo: BoundField, HeaderText: Contributi sociali, DataField: CotisationsSociales, DataFormatString: {0:C} | |
Tipo: BoundField, HeaderText: Stipendio netto, DataField: SalaireNet, DataFormatString: {0:C} |
Si presti attenzione al fatto che il campo [DataField] deve corrispondere a una proprietà esistente della classe [Simulation]. Al termine di questa fase, sono state create tutte le colonne di tipo [BoundField]:
![]() |
- in [1]: le colonne create per [GridView]
- in [2]: la generazione automatica delle colonne deve essere disabilitata quando è lo sviluppatore stesso a definirle, come abbiamo appena fatto.
Resta da creare la colonna dei link [Retirer]:

![]() |
- in [1]: aggiungere una colonna di tipo [CommandField / Supprimer]
- in [2]: ButtonType=Link per avere un link nella colonna anziché un pulsante
- da [3] a CausesValidation=False: cliccando sul link non verranno eseguiti i controlli di validazione presenti nella pagina. Infatti, l'eliminazione di una simulazione non richiede alcuna verifica dei dati.
- in [4]: sarà visibile solo il link di eliminazione.
- in [5]: il testo di questo link
8.5.6. La vista [SimulationsVides]
Il componente [View] denominato [VueSimulationsVides] contiene semplicemente del testo:
8.5.7. La vista [Erreurs]
Il componente [View] denominato [VueErreurs] è il seguente:
![]() |
N. | Tipo | Nome | Ruolo |
Ripetitore | RptErreurs | visualizza un elenco di messaggi di errore |
Il componente [Repeater] consente di ripetere un codice ASP.NET / HTML per ogni oggetto di una fonte di dati, solitamente una raccolta. Questo codice è definito direttamente nel codice sorgente ASP.NET della pagina:
<asp:Repeater ID="RptErreurs" runat="server">
<ItemTemplate>
<li>
<%# Container.DataItem %>
</li>
</ItemTemplate>
</asp:Repeater>
- riga 2: <ItemTemplate> definisce il codice che verrà ripetuto per ogni elemento della fonte dati.
- riga 4: visualizza il valore dell’espressione Container.DataItem che indica l’elemento corrente della fonte dati. Poiché tale elemento è un oggetto, viene utilizzato il metodo ToString di tale oggetto per includerlo nel flusso HTML della pagina. La nostra collezione di oggetti sarà una collezione List(Of String) contenente messaggi di errore. Le righe 3-5 includeranno sequenze <li>Message</li> nel flusso HTML della pagina.
8.6. Il controller [Default.aspx.cs]
8.6.1. Panoramica
Torniamo all’architettura MVC dell’applicazione:
![]() |
- [Default.aspx.cs], che è il codice di controllo della singola pagina [Default.aspx], è il controller dell’applicazione.
- [Global] è l’oggetto di tipo [HttpApplication] che inizializza l’applicazione e che dispone di un riferimento al livello [métier].
Lo scheletro del codice del controller [Default.aspx.cs] è il seguente:
using System.Collections.Generic;
...
public partial class PagePam : Page
{
private void setVues(bool boolVues1, bool boolVues2, int index)
{
// vengono visualizzate le viste richieste
// boolVues1: true se la vista multipla Viste1 deve essere visibile
// boolVues1: true se il gruppo di viste Viste2 deve essere visibile
// index: indice della vista di Vues2 da visualizzare
...
}
private void setMenu(bool boolFaireSimulation, bool boolEnregistrerSimulation, bool boolEffacerSimulation, bool boolFormulaireSimulation, bool boolVoirSimulations, bool boolTerminerSession)
{
// si impostano le opzioni del menu
// ogni valore booleano viene assegnato alla proprietà Visibile del collegamento corrispondente
...
}
// caricamento della pagina
protected void Page_Load(object sender, System.EventArgs e)
{
// elaborazione della richiesta iniziale
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)
{
...
}
}
Alla richiesta iniziale (GET) dell’utente, viene elaborato solo l’evento Load delle righe 24-31. Alle richieste successive (POST) effettuate tramite i link del menu, vengono elaborati due eventi:
- l'evento Load (24-31), ma il test del valore booleano Page.IsPostback (riga 27) fa sì che non venga eseguita alcuna azione;
- l’evento associato al link su cui è stato cliccato:
![]() |
- righe 33-36: gestiscono il clic sul link [1]
- righe 38-41: gestiscono il clic sul link [2]
- righe 43-46: gestiscono il clic sul link [3]
- righe 58-61: gestiscono il clic sul link [4]
- righe 48-51: gestiscono il clic sul link [5]
- righe 53-56: gestiscono il clic sul link [6]
Per raggruppare sequenze di codice che ricorrono spesso, sono stati creati due metodi interni:
- setVues, righe 7-14: imposta la vista o le viste da visualizzare
- setMenu, righe 16-21: definisce le opzioni di menu da visualizzare
8.6.2. L'evento Load
Letture consigliate: riferimento [1], Sviluppo WEB con ASP.NET 1.1:
- paragrafo Componente [Repeater] e collegamento dei dati.
La prima schermata presentata all'utente è quella del modulo vuoto:

L’inizializzazione dell’applicazione richiede l’accesso a una fonte di dati che potrebbe non andare a buon fine. In tal caso, la prima pagina visualizzata è una pagina di errore:

L'evento [Load] viene gestito in modo analogo a quello delle versioni precedenti ASP.NET:
// caricamento della pagina
protected void Page_Load(object sender, System.EventArgs e)
{
// elaborazione della richiesta iniziale
if (!IsPostBack)
{
// Errori di inizializzazione?
if (Global.Erreur)
{
// visualizzazione della vista [erreurs]
...
// posizionamento del menu
...
return;
}
// caricamento dei nomi dei dipendenti nel menu a tendina
...
// Posizionamento del menu
...
// visualizzazione vista [saisie]
...
}
}
Domanda: completare il codice sopra riportato
8.6.3. Azione: eseguire la simulazione
Di seguito, la schermata contrassegnata con (1) è quella della richiesta dell'utente, mentre quella contrassegnata con (2) è la risposta inviata dall'applicazione web. Dalla schermata iniziale, l'utente può avviare una simulazione:


![]() |
La procedura che gestisce questa azione potrebbe essere simile alla seguente:
protected void LinkButtonFaireSimulation_Click(object sender, System.EventArgs e)
{
// calcolo dello stipendio
// pagina valida?
Page.Validate();
if (!Page.IsValid)
{
// visualizzazione vista [saisie]
...
return;
}
// la pagina è valida - si recuperano i dati inseriti
double HeuresTravaillées = ...;
int JoursTravaillés = ...;
// si calcola lo stipendio del dipendente
FeuilleSalaire feuillesalaire;
try
{
feuillesalaire = ...
}
catch (PamException ex)
{
// visualizzazione della vista [erreurs]
...
return;
}
// il risultato viene inserito nella sessione
Session["simulation"] = ...
// visualizzazione dei risultati
...
// visualizzazione delle viste [saisie, employe, salaire]
...
// visualizzazione del menu
...
}
Domanda: completare il codice sopra riportato
8.6.4. Azione: salvare la simulazione
Una volta effettuata la simulazione, l’utente può richiederne la registrazione:
![]() |

La procedura che gestisce questa azione potrebbe essere simile alla seguente:
protected void LinkButtonEnregistrerSimulation_Click(object sender, System.EventArgs e)
{
// si salva la simulazione corrente nell'elenco delle simulazioni presente nella sessione
...
// visualizza la vista [simulations]
...
}
Domanda: completare il codice sopra riportato
8.6.5. Azione: Ritorno al modulo di simulazione
Letture consigliate: riferimento [1], [Développement WEB avec ASP.NET 1.1 ]: il ruolo del campo nascosto _VIEWSTATE
Una volta visualizzato l’elenco delle simulazioni, l’utente può richiedere di tornare al modulo di simulazione:
![]() |
Si noti che la schermata (2) mostra il modulo così come è stato compilato. È importante ricordare che queste diverse viste appartengono alla stessa pagina. Tra le diverse richieste, i valori dei componenti vengono mantenuti dal meccanismo ViewState se tali componenti hanno la proprietà EnableViewState impostata su true.
La procedura che gestisce questa azione potrebbe essere simile alla seguente:
protected void LinkButtonFormulaireSimulation_Click(object sender, System.EventArgs e)
{
// visualizzazione vista [saisie]
...
// posizionamento del menu
...
}
Domanda: completare il codice sopra riportato
8.6.6. Azione: Cancella la simulazione
Una volta tornato al modulo di simulazione, l’utente può richiedere di cancellare i dati inseriti:
![]() |
La procedura che gestisce questa azione potrebbe essere simile alla seguente:
protected void LinkButtonEffacerSimulation_Click(object sender, System.EventArgs e)
{
// RAZ del modulo
...
}
Domanda: completare il codice sopra riportato
8.6.7. Azione: Visualizza le simulazioni
L'utente può richiedere di visualizzare le simulazioni che ha già effettuato:
![]() |
![]() |
La procedura che gestisce questa azione potrebbe essere simile alla seguente:
protected void LinkButtonVoirSimulations_Click(object sender, System.EventArgs e)
{
// si recuperano le simulazioni nella sessione
...
// ci sono simulazioni?
if (...)
{
// vista [simulations] visibile
...
}
else
{
// vista [SimulationsVides]
...
}
// si imposta il menu
...
}
Domanda: completare il codice sopra riportato
8.6.8. Azione: eliminare una simulazione
L'utente può richiedere l'eliminazione di una simulazione:
![]() |
![]() |
La procedura [GridViewSimulations_RowDeleting ] che gestisce questa azione potrebbe essere simile alla seguente:
protected void GridViewSimulations_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
// si recuperano le simulazioni nella sessione
...
// si elimina la simulazione indicata (e.RowIndex è il numero della riga eliminata)
...
// ci sono ancora delle simulazioni?
if (...)
{
// si compila il file GridView
...
}
else
{
// vista [SimulationsVides]
...
}
}
Domanda: completare il codice sopra riportato
8.6.9. Azione: Terminare la sessione
L'utente può richiedere di terminare la propria sessione di simulazioni. Ciò comporta l'abbandono del contenuto della sessione e la visualizzazione di un modulo vuoto:
![]() |
![]() |
La procedura che gestisce questa azione potrebbe essere simile alla seguente:
protected void LinkButtonTerminerSession_Click(object sender, System.EventArgs e)
{
// si chiude la sessione
...
// visualizza la vista [saisies]
...
// posizionamento del menu
...
}
Domanda: completare il codice sopra riportato
Esercitazione pratica: implementare sul computer l'applicazione web precedente. Aggiungervi un comportamento Ajax.






















