Con il rilascio ufficiale del .NET Framework 4.6 avvenuto lo scorso luglio, Microsoft introduce alcuni miglioramenti che interessano anche le applicazioni ASP.NET WebForms.
Si tratta di un aggiornamento in-place della precedente versione 4.5.2, che può essere scaricato dai canali ufficiali http://aspit.co/a6g ed installato su sistemi operativi Windows Server 2008 SP2 (o superiore) e, per il desktop, da Windows Vista SP2.
Nel caso in cui non abbiate ancora effettuato l'aggiornamento a Visual Studio 2015, potrete comunque beneficiare di queste nuove funzionalità da Visual Studio 2012 o 2013 scaricando l'apposito Targeting Pack http://aspit.co/a6h ed impostando il .NET Framework 4.6 come framework di destinazione del vostro progetto.
Il miglioramento di cui parleremo oggi è il supporto al model binding asincrono.
Il model binding è una funzionalità nata con ASP.NET MVC, reinterpretata successivamente per ASP.NET WebForms che permette ad un databound control come la GridView di scambiare dati con i nostri metodi di business, anziché con sorgenti come il SqlDataSource.
Marco De Sanctis ne ha già fornito un esempio in un suo precedente script:
http://aspit.co/aju
Con il .NET Framework 4.6, il model binding per ASP.NET WebForms diventa ancor più efficiente perché in grado di sfruttare metodi asincroni per l'ottenimento e l'aggiornamento dei dati, a tutto vantaggio delle prestazioni della nostra applicazione web, soprattutto in condizioni di carico elevato.
Iniziamo aggiungendo l'attributo Async="true" alla direttiva @Page, che ci abiliterà all'uso dei metodi asincroni.
<%@ Page Async="true" %>
Nel markup della WebForm, aggiungiamo una GridView che useremo per visualizzare e gestire gli elementi esistenti. Inoltre, aggiungiamo un DetailsView per inserirne di nuovi.
<!-- GridView per visualizzare, modificare ed eliminare prodotti esistenti --> <h2>Lista prodotti</h2> <asp:GridView ID="ProductsList" ItemType="Model.Product" DataKeyNames="ProductId" runat="server" AutoGenerateColumns="false" AutoGenerateEditButton="true" AutoGenerateDeleteButton="true" SelectMethod="ReadProducts" UpdateMethod="UpdateProduct" DeleteMethod="DeleteProduct"> <Columns> <asp:BoundField HeaderText="Id" DataField="ProductId" ReadOnly="true" /> <asp:BoundField HeaderText="Descrizione" DataField="Description" /> <asp:BoundField HeaderText="Prezzo in euro" DataField="PriceInEuro" /> </Columns> </asp:GridView> <!-- DetailsView per creare nuovi prodotti --> <h2>Nuovo prodotto</h2> <asp:DetailsView ItemType="Model.Product" DataKeyNames="ProductId" runat="server" DefaultMode="Insert" AutoGenerateRows="false" AutoGenerateInsertButton="true" InsertMethod="CreateProduct"> <Fields> <asp:BoundField HeaderText="Descrizione" DataField="Description" /> <asp:BoundField HeaderText="Prezzo" DataField="PriceInEuro" /> </Fields> </asp:DetailsView>
Il punto interessante di questo esempio risiede negli attributi SelectMethod, UpdateMethod, DeleteMethod e CreateMethod che abbiamo valorizzato con i nomi di metodi asincroni che andremo a creare nel codefile della pagina.
Apriamo dunque il file .aspx.cs ed aggiungiamo i seguenti metodi, resi asincroni dalla parola chiave async e dal tipo Task restituito.
public async Task<IEnumerable<Product>> ReadProducts() { using (var context = new MyOnlineStoreContext()) { // Estraggo l'elenco dei prodotti in maniera asincrona return await context.Products.ToListAsync(); } } public async Task UpdateProduct(Product product) { if (!ModelState.IsValid) return; using (var context = new MyOnlineStoreContext()) { context.Entry(product).State = EntityState.Modified; // Aggiorno il prodotto in maniera asincrona await context.SaveChangesAsync(); } } public async Task DeleteProduct(Product product) { using (var context = new MyOnlineStoreContext()) { context.Entry(product).State = EntityState.Deleted; // Elimino il prodotto in maniera asincrona await context.SaveChangesAsync(); } } public async Task CreateProduct(Product product) { if (!ModelState.IsValid) return; using (var context = new MyOnlineStoreContext()) { context.Entry(product).State = EntityState.Added; // Aggiungo il prodotto in maniera asincrona await context.SaveChangesAsync(); } //Indico alla GridView che deve riottenere l'elenco dei prodotti ProductsList.DataBind(); }
In questo modo, possiamo sfruttare appieno le tecnologie che, a loro volta, espongono API asincrone come Entity Framework 6. Nell'esempio mostrato, la parola chiave await, che viene usata con i metodi ToListAsync e SaveChangesAsync, permette ad IIS di riutilizzare in maniera intelligente i thread di elaborazione delle richieste web, così che non restino bloccati e inutilizzati in attesa che la lettura o la scrittura al database si completi.
Il model binding asincrono diventa ancor più consigliato quando consumiamo risorse soggette ad una latenza di rete consistente, come ad esempio web services o altro tipo di servizi che siano ospitati su macchine remote o nel cloud.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Evitare il flickering dei componenti nel prerender di Blazor 8
Ordinare randomicamente una lista in C#
Configurare e gestire sidecar container in Azure App Service
Bloccare l'esecuzione di un pod in mancanza di un'artifact attestation di GitHub
Migliorare i tempi di risposta di GPT tramite lo streaming endpoint in ASP.NET Core
Ottimizzare le pull con Artifact Cache di Azure Container Registry
Scrivere selettori CSS più semplici ed efficienti con :is()
Utilizzare il nuovo modello GPT-4o con Azure OpenAI
Effettuare il binding di date in Blazor
Estrarre dati randomici da una lista di oggetti in C#
Paginare i risultati con QuickGrid in Blazor
Creare una libreria CSS universale: Cards