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
Implementare l'infinite scroll con QuickGrid in Blazor Server
Introduzione alle Container Queries
Effettuare il log delle chiamate a function di GPT in ASP.NET Web API
Utilizzare Copilot con Azure Cosmos DB
Utilizzare un service principal per accedere a Azure Container Registry
Il nuovo controllo Range di Blazor 9
Applicare un filtro per recuperare alcune issue di GitHub
Sfruttare gli embedding e la ricerca vettoriale con Azure SQL Database
Miglioramenti agli screen reader e al contrasto in Angular
Ottimizzare la latenza in Blazor 8 tramite InteractiveAuto render mode
Ottimizzazione dei block template in Angular 17
Utilizzare il trigger SQL con le Azure Function
I più letti di oggi
- Simulare Azure Cosmos DB in locale con Docker
- Utilizzare il metodo Index di LINQ per scorrere una lista sapendo anche l'indice dell'elemento
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- .NET Conference Italia 2024 - Milano
- .NET Conference Italia 2023 - Milano e Online